# HG changeset patch # User Aziz K?ksal # Date 1219333864 -7200 # Node ID 4063da6f3eddf052bf01055f287ee223d436b5de # Parent 1ecf05e680bacd3e56abacda411b3b779e3f072e Refactored the config file and how it is loaded. diff -r 1ecf05e680ba -r 4063da6f3edd src/Settings.d --- a/src/Settings.d Wed Aug 20 20:39:16 2008 +0200 +++ b/src/Settings.d Thu Aug 21 17:51:04 2008 +0200 @@ -9,6 +9,8 @@ struct GlobalSettings { static: + /// Path to the data directory. + string dataDir = "data/"; /// Predefined version identifiers. string[] versionIds; /// Path to the language file. diff -r 1ecf05e680ba -r 4063da6f3edd src/SettingsLoader.d --- a/src/SettingsLoader.d Wed Aug 20 20:39:16 2008 +0200 +++ b/src/SettingsLoader.d Thu Aug 21 17:51:04 2008 +0200 @@ -16,9 +16,11 @@ import common; import tango.io.FilePath; +import tango.sys.Environment; +import tango.text.Util : substitute; /// Loads settings from a D module file. -class SettingsLoader +abstract class SettingsLoader { InfoManager infoMan; /// Collects error messages. Module mod; /// Current module. @@ -28,11 +30,6 @@ this.infoMan = infoMan; } - static SettingsLoader opCall(InfoManager infoMan) - { - return new SettingsLoader(infoMan); - } - /// Creates an error report. /// Params: /// token = where the error occurred. @@ -71,12 +68,50 @@ } void load() + {} +} + +/// Loads the configuration file of dil. +class ConfigLoader : SettingsLoader +{ + static string configFileName = "config.d"; /// Name of the configuration file. + string executablePath; /// Absolute path to the executable of dil. + string executableDir; /// Absolte path to the directory of the executable of dil. + string dataDir; /// Absolute path to dil's data directory. + string homePath; /// Path to the home directory. + + this(InfoManager infoMan) { - scope execPath = new FilePath(GetExecutableFilePath()); - execPath = new FilePath(execPath.folder()); + super(infoMan); + } + + static ConfigLoader opCall(InfoManager infoMan) + { + return new ConfigLoader(infoMan); + } - // Load config.d - auto filePath = resolvePath(execPath, "config.d"); + string expandVariables(string val) + { + val = substitute(val, "${DATADIR}", dataDir); + val = substitute(val, "${HOME}", homePath); + val = substitute(val, "${EXECDIR}", executableDir); + return val; + } + + void load() + { + homePath = Environment.get("HOME"); + executablePath = GetExecutableFilePath(); + executableDir = (new FilePath(executablePath)).folder(); + + // Load the configuration file. + auto filePath = findConfigurationFilePath(); + if (filePath is null) + { + infoMan ~= new Error(new Location("",0), + "the configuration file "~configFileName~" could not be found."); + return; + } mod = new Module(filePath, infoMan); mod.parse(); @@ -87,33 +122,40 @@ auto pass1 = new SemanticPass1(mod, context); pass1.run(); - if (auto array = getValue!(ArrayInitExpression)("version_ids")) + // Initialize the dataDir member. + if (auto val = getValue!(StringExpression)("DATADIR")) + dataDir = val.getString(); + dataDir = resolvePath(executableDir, dataDir); + GlobalSettings.dataDir = dataDir; + + if (auto array = getValue!(ArrayInitExpression)("VERSION_IDS")) foreach (value; array.values) - if (auto str = castTo!(StringExpression)(value)) - GlobalSettings.versionIds ~= str.getString(); - if (auto val = getValue!(StringExpression)("langfile")) - GlobalSettings.langFile = val.getString(); - if (auto array = getValue!(ArrayInitExpression)("import_paths")) - foreach (value; array.values) - if (auto str = castTo!(StringExpression)(value)) - GlobalSettings.importPaths ~= str.getString(); - if (auto array = getValue!(ArrayInitExpression)("ddoc_files")) + if (auto val = castTo!(StringExpression)(value)) + GlobalSettings.versionIds ~= val.getString(); + if (auto val = getValue!(StringExpression)("LANG_FILE")) + GlobalSettings.langFile = expandVariables(val.getString()); + if (auto array = getValue!(ArrayInitExpression)("IMPORT_PATHS")) foreach (value; array.values) - if (auto str = castTo!(StringExpression)(value)) - GlobalSettings.ddocFilePaths ~= resolvePath(execPath, str.getString()); - if (auto val = getValue!(StringExpression)("xml_map")) - GlobalSettings.xmlMapFile = val.getString(); - if (auto val = getValue!(StringExpression)("html_map")) - GlobalSettings.htmlMapFile = val.getString(); - if (auto val = getValue!(StringExpression)("lexer_error")) + if (auto val = castTo!(StringExpression)(value)) + GlobalSettings.importPaths ~= expandVariables(val.getString()); + if (auto array = getValue!(ArrayInitExpression)("DDOC_FILES")) + foreach (value; array.values) + if (auto val = castTo!(StringExpression)(value)) + GlobalSettings.ddocFilePaths ~= expandVariables(val.getString()); + if (auto val = getValue!(StringExpression)("XML_MAP")) + GlobalSettings.xmlMapFile = expandVariables(val.getString()); + if (auto val = getValue!(StringExpression)("HTML_MAP")) + GlobalSettings.htmlMapFile = expandVariables(val.getString()); + if (auto val = getValue!(StringExpression)("LEXER_ERROR")) GlobalSettings.lexerErrorFormat = val.getString(); - if (auto val = getValue!(StringExpression)("parser_error")) + if (auto val = getValue!(StringExpression)("PARSER_ERROR")) GlobalSettings.parserErrorFormat = val.getString(); - if (auto val = getValue!(StringExpression)("semantic_error")) + if (auto val = getValue!(StringExpression)("SEMANTIC_ERROR")) GlobalSettings.semanticErrorFormat = val.getString(); // Load language file. - filePath = resolvePath(execPath, GlobalSettings.langFile); + // TODO: create a separate class for this? + filePath = expandVariables(GlobalSettings.langFile); mod = new Module(filePath); mod.parse(); @@ -127,8 +169,8 @@ { char[][] messages; foreach (value; array.values) - if (auto str = castTo!(StringExpression)(value)) - messages ~= str.getString(); + if (auto val = castTo!(StringExpression)(value)) + messages ~= val.getString(); if (messages.length != MID.max+1) error(mod.firstToken, "messages table in {} must exactly have {} entries, but not {}.", @@ -139,6 +181,31 @@ if (auto val = getValue!(StringExpression)("lang_code")) GlobalSettings.langCode = val.getString(); } + + /// Searches for the configuration file of dil. + /// Returns: the filePath or null if the file couldn't be found. + string findConfigurationFilePath() + { + // 1. Look in environment variable DILCONF. + auto filePath = new FilePath(Environment.get("DILCONF")); + if (filePath.exists()) + return filePath.toString(); + // 2. Look in the current working directory. + filePath.set(this.configFileName); + if (filePath.exists()) + return filePath.toString(); + // 3. Look in the directory set by HOME. + filePath.set(this.homePath); + filePath.append(this.configFileName); + if (filePath.exists()) + return filePath.toString(); + // 4. Look in the binary's directory. + filePath.set(this.executableDir); + filePath.append(this.configFileName); + if (filePath.exists()) + return filePath.toString(); + return null; + } } /// Loads an associative array from a D module file. @@ -183,11 +250,13 @@ /// Resolves the path to a file from the executable's dir path /// if it is relative. /// Returns: filePath if it is absolute or execPath + filePath. -string resolvePath(FilePath execPath, string filePath) +string resolvePath(string execPath, string filePath) { - if ((new FilePath(filePath)).isAbsolute()) + scope path = new FilePath(filePath); + if (path.isAbsolute()) return filePath; - return execPath.dup.append(filePath).toString(); + path.set(execPath).append(filePath); + return path.toString(); } version(DDoc) diff -r 1ecf05e680ba -r 4063da6f3edd src/config.d --- a/src/config.d Wed Aug 20 20:39:16 2008 +0200 +++ b/src/config.d Thu Aug 21 17:51:04 2008 +0200 @@ -1,34 +1,57 @@ /// The configuration file of dil. /// -/// Relative paths are resolved from the directory of the executable. +/// The file is searched for in the following order: +/// $(OL +/// $(LI The environment variable DILCONF.) +/// $(LI The current working directory.) +/// $(LI The directory set in the environment variable HOME.) +/// $(LI The executable's directory.) +/// ) +/// The program will fail with an error msg if the file couldn't be found.$(BR) +/// +/// The following variables are expanded inside strings (only where paths are expected): +/// $(UL +/// $(LI ${DATADIR} -> the data directory of dil (e.g. /home/user/dil/bin/data or C:\dil\bin\data).) +/// $(LI ${HOME} -> the home directory (e.g. /home/name or C:\Documents and Settings\name).) +/// $(LI ${EXECDIR} -> the absolute path to the directory of dil's executable (e.g. /home/name/dil/bin).) +/// ) module config; +/// Files needed by dil are located in this directory. +/// +/// A relative path is resolved from the directory of dil's executable. +var DATADIR = "data/"; + /// Predefined version identifiers. -var version_ids = ["X86", "linux", "LittleEndian"]; +var VERSION_IDS = ["X86", "linux", "LittleEndian"]; // "X86_64", "Windows", "Win32", "Win64", "BigEndian" -/// Path to the language file. -var langfile = "lang_en.d"; - /// An array of import paths to look for modules. -var import_paths = []; /// E.g.: ["src/", "import/"] +/// +/// Relative paths are resolved from the current working directory. +var IMPORT_PATHS = []; /// E.g.: ["src/", "import/"] /// DDoc macro file paths. /// -/// Macro definitions in ddoc_files[n] override the ones in ddoc_files[n-1]. -var ddoc_files = ["predefined.ddoc"]; /// E.g.: ["src/mymacros.ddoc", "othermacros.ddoc"] +/// Macro definitions in ddoc_files[n] override the ones in ddoc_files[n-1].$(BR) +/// Relative paths are resolved from the current working directory. +var DDOC_FILES = ["${DATADIR}/predefined.ddoc"]; /// E.g.: ["src/mymacros.ddoc", "othermacros.ddoc"] -var xml_map = "xml_map.d"; -var html_map = "html_map.d"; +/// Path to the language file. +var LANG_FILE = "${DATADIR}/lang_en.d"; +/// Path to the xml map. +var XML_MAP = "${DATADIR}/xml_map.d"; +/// Path to the html map. +var HTML_MAP = "${DATADIR}/html_map.d"; /// Customizable formats for error messages. /// -/// -var lexer_error = "{0}({1},{2})L: {3}"; -var parser_error = "{0}({1},{2})P: {3}"; /// ditto -var semantic_error = "{0}({1},{2})S: {3}"; /// ditto +/// $(UL +/// $(LI 0: file path to the source text.) +/// $(LI 1: line number.) +/// $(LI 2: column number.) +/// $(LI 3: error message.) +/// ) +var LEXER_ERROR = "{0}({1},{2})L: {3}"; +var PARSER_ERROR = "{0}({1},{2})P: {3}"; /// ditto +var SEMANTIC_ERROR = "{0}({1},{2})S: {3}"; /// ditto diff -r 1ecf05e680ba -r 4063da6f3edd src/main.d --- a/src/main.d Wed Aug 20 20:39:16 2008 +0200 +++ b/src/main.d Thu Aug 21 17:51:04 2008 +0200 @@ -46,7 +46,7 @@ void main(char[][] args) { auto infoMan = new InfoManager(); - SettingsLoader.SettingsLoader(infoMan).load(); + ConfigLoader(infoMan).load(); if (infoMan.hasInfo) return printErrors(infoMan); @@ -391,6 +391,8 @@ errorFormat = GlobalSettings.semanticErrorFormat; else if (info.classinfo is Warning.classinfo) errorFormat = "{0}: Warning: {3}"; + else if (info.classinfo is dil.Information.Error.classinfo) + errorFormat = "Error: {3}"; else continue; auto err = cast(Problem)info;