Mercurial > projects > dil
comparison trunk/src/SettingsLoader.d @ 779:8e6fed11bb68
Moved Settings.d and SettingsLoader.d to src/.
author | Aziz K?ksal <aziz.koeksal@gmail.com> |
---|---|
date | Wed, 20 Feb 2008 22:47:33 +0100 |
parents | trunk/src/dil/SettingsLoader.d@78be32e3e157 |
children | c24be8d4f6ab |
comparison
equal
deleted
inserted
replaced
778:78be32e3e157 | 779:8e6fed11bb68 |
---|---|
1 /++ | |
2 Author: Aziz Köksal | |
3 License: GPL3 | |
4 +/ | |
5 module SettingsLoader; | |
6 | |
7 import Settings; | |
8 import dil.Messages; | |
9 import dil.ast.Node, dil.ast.Declarations, dil.ast.Expressions; | |
10 import dil.semantic.Module; | |
11 import dil.semantic.Pass1; | |
12 import dil.semantic.Symbol; | |
13 import dil.semantic.Symbols; | |
14 import dil.Information; | |
15 import dil.Compilation; | |
16 import common; | |
17 | |
18 import tango.io.FilePath; | |
19 | |
20 class SettingsLoader | |
21 { | |
22 InfoManager infoMan; | |
23 Module mod; /// Current module. | |
24 | |
25 this(InfoManager infoMan) | |
26 { | |
27 this.infoMan = infoMan; | |
28 } | |
29 | |
30 static SettingsLoader opCall(InfoManager infoMan) | |
31 { | |
32 return new SettingsLoader(infoMan); | |
33 } | |
34 | |
35 void error(Token* token, char[] formatMsg, ...) | |
36 { | |
37 auto location = token.getErrorLocation(); | |
38 auto msg = Format(_arguments, _argptr, formatMsg); | |
39 infoMan ~= new SemanticError(location, msg); | |
40 } | |
41 | |
42 T getValue(T)(char[] name) | |
43 { | |
44 auto var = mod.lookup(name); | |
45 if (!var) // Returning T.init instead of null, because dmd gives an error. | |
46 return error(mod.firstToken, "variable '{}' is not defined", name), T.init; | |
47 auto t = var.node.begin; | |
48 if (!var.isVariable) | |
49 return error(t, "'{}' is not a variable declaration", name), T.init; | |
50 auto value = var.to!(Variable).value; | |
51 if (!value) | |
52 return error(t, "'{}' variable has no value set", name), T.init; | |
53 T val = value.Is!(T); // Try casting to T. | |
54 if (!val) | |
55 error(value.begin, "the value of '{}' is not of type {}", name, typeof(T).stringof); | |
56 return val; | |
57 } | |
58 | |
59 T castTo(T)(Node n) | |
60 { | |
61 char[] type; | |
62 is(T == StringExpression) && (type = "char[]"); | |
63 if (!n.Is!(T)) | |
64 error(n.begin, "expression is not of type {}", type); | |
65 return n.Is!(T); | |
66 } | |
67 | |
68 void load() | |
69 { | |
70 scope execPath = new FilePath(GetExecutableFilePath()); | |
71 execPath = new FilePath(execPath.folder()); | |
72 | |
73 // Load config.d | |
74 auto filePath = resolvePath(execPath, "config.d"); | |
75 mod = new Module(filePath, infoMan); | |
76 mod.parse(); | |
77 | |
78 if (mod.hasErrors) | |
79 return; | |
80 | |
81 auto context = new CompilationContext; | |
82 auto pass1 = new SemanticPass1(mod, context); | |
83 pass1.start(); | |
84 | |
85 if (auto array = getValue!(ArrayInitExpression)("version_ids")) | |
86 foreach (value; array.values) | |
87 if (auto str = castTo!(StringExpression)(value)) | |
88 GlobalSettings.versionIds ~= str.getString(); | |
89 if (auto val = getValue!(StringExpression)("langfile")) | |
90 GlobalSettings.langFile = val.getString(); | |
91 if (auto array = getValue!(ArrayInitExpression)("import_paths")) | |
92 foreach (value; array.values) | |
93 if (auto str = castTo!(StringExpression)(value)) | |
94 GlobalSettings.importPaths ~= str.getString(); | |
95 if (auto array = getValue!(ArrayInitExpression)("ddoc_files")) | |
96 foreach (value; array.values) | |
97 if (auto str = castTo!(StringExpression)(value)) | |
98 GlobalSettings.ddocFilePaths ~= resolvePath(execPath, str.getString()); | |
99 if (auto val = getValue!(StringExpression)("xml_map")) | |
100 GlobalSettings.xmlMapFile = val.getString(); | |
101 if (auto val = getValue!(StringExpression)("html_map")) | |
102 GlobalSettings.htmlMapFile = val.getString(); | |
103 if (auto val = getValue!(StringExpression)("lexer_error")) | |
104 GlobalSettings.lexerErrorFormat = val.getString(); | |
105 if (auto val = getValue!(StringExpression)("parser_error")) | |
106 GlobalSettings.parserErrorFormat = val.getString(); | |
107 if (auto val = getValue!(StringExpression)("semantic_error")) | |
108 GlobalSettings.semanticErrorFormat = val.getString(); | |
109 | |
110 // Load language file. | |
111 filePath = resolvePath(execPath, GlobalSettings.langFile); | |
112 mod = new Module(filePath); | |
113 mod.parse(); | |
114 | |
115 if (mod.hasErrors) | |
116 return; | |
117 | |
118 pass1 = new SemanticPass1(mod, context); | |
119 pass1.start(); | |
120 | |
121 if (auto array = getValue!(ArrayInitExpression)("messages")) | |
122 { | |
123 char[][] messages; | |
124 foreach (value; array.values) | |
125 if (auto str = castTo!(StringExpression)(value)) | |
126 messages ~= str.getString(); | |
127 if (messages.length != MID.max+1) | |
128 error(mod.firstToken, | |
129 "messages table in {} must exactly have {} entries, but not {}.", | |
130 filePath, MID.max+1, messages.length); | |
131 GlobalSettings.messages = messages; | |
132 dil.Messages.SetMessages(messages); | |
133 } | |
134 if (auto val = getValue!(StringExpression)("lang_code")) | |
135 GlobalSettings.langCode = val.getString(); | |
136 } | |
137 } | |
138 | |
139 class TagMapLoader : SettingsLoader | |
140 { | |
141 this(InfoManager infoMan) | |
142 { | |
143 super(infoMan); | |
144 } | |
145 | |
146 static TagMapLoader opCall(InfoManager infoMan) | |
147 { | |
148 return new TagMapLoader(infoMan); | |
149 } | |
150 | |
151 string[string] load(string filePath) | |
152 { | |
153 mod = new Module(filePath, infoMan); | |
154 mod.parse(); | |
155 if (mod.hasErrors) | |
156 return null; | |
157 | |
158 auto context = new CompilationContext; | |
159 auto pass1 = new SemanticPass1(mod, context); | |
160 pass1.start(); | |
161 | |
162 string[string] map; | |
163 if (auto array = getValue!(ArrayInitExpression)("map")) | |
164 foreach (i, value; array.values) | |
165 { | |
166 auto key = array.keys[i]; | |
167 if (auto valExp = castTo!(StringExpression)(value)) | |
168 if (!key) | |
169 error(value.begin, "expected key : value"); | |
170 else if (auto keyExp = castTo!(StringExpression)(key)) | |
171 map[keyExp.getString()] = valExp.getString(); | |
172 } | |
173 return map; | |
174 } | |
175 } | |
176 | |
177 string resolvePath(FilePath execPath, string filePath) | |
178 { | |
179 if ((new FilePath(filePath)).isAbsolute()) | |
180 return filePath; | |
181 return execPath.dup.append(filePath).toString(); | |
182 } | |
183 | |
184 version(DDoc) | |
185 { | |
186 /// Returns the fully qualified path to this executable. | |
187 char[] GetExecutableFilePath(); | |
188 } | |
189 else version(Windows) | |
190 { | |
191 private extern(Windows) uint GetModuleFileNameA(void*, char*, uint); | |
192 | |
193 char[] GetExecutableFilePath() | |
194 { | |
195 alias GetModuleFileNameA GetModuleFileName; | |
196 char[] buffer = new char[256]; | |
197 uint count; | |
198 | |
199 while (1) | |
200 { | |
201 if (buffer is null) | |
202 return null; | |
203 | |
204 count = GetModuleFileName(null, buffer.ptr, buffer.length); | |
205 if (count == 0) | |
206 return null; | |
207 if (buffer.length != count && buffer[count] == 0) | |
208 break; | |
209 // Increase size of buffer | |
210 buffer.length = buffer.length * 2; | |
211 } | |
212 assert(buffer[count] == 0); | |
213 // Reduce buffer to the actual length of the string (excluding '\0'.) | |
214 if (count < buffer.length) | |
215 buffer.length = count; | |
216 return buffer; | |
217 } | |
218 } | |
219 else version(linux) | |
220 { | |
221 private extern(C) size_t readlink(char* path, char* buf, size_t bufsize); | |
222 | |
223 char[] GetExecutableFilePath() | |
224 { | |
225 char[] buffer = new char[256]; | |
226 size_t count; | |
227 | |
228 while (1) | |
229 { | |
230 // This won't work on very old Linux systems. | |
231 count = readlink("/proc/self/exe".ptr, buffer.ptr, buffer.length); | |
232 if (count == -1) | |
233 return null; | |
234 if (count < buffer.length) | |
235 break; | |
236 buffer.length = buffer.length * 2; | |
237 } | |
238 buffer.length = count; | |
239 return buffer; | |
240 } | |
241 } | |
242 else | |
243 static assert(0, "GetExecutableFilePath() is not implemented on this platform."); |