blob: 01611ad335643baa8539c53ad0f9d1032605afed [file] [log] [blame]
Reid Spencercbabe7f2004-08-19 21:17:53 +00001//===- Configuration.cpp - Configuration Data Mgmt --------------*- C++ -*-===//
Reid Spencer2594c9a2004-08-13 20:21:22 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Reid Spencer and is distributed under the
6// University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the parsing of configuration files for the LLVM Compiler
11// Driver (llvmc).
12//
13//===------------------------------------------------------------------------===
14
Reid Spencerf51a87c2004-08-19 21:52:49 +000015#include "Configuration.h"
Reid Spencer68fb37a2004-08-14 09:37:15 +000016#include "ConfigLexer.h"
Reid Spencer2594c9a2004-08-13 20:21:22 +000017#include "CompilerDriver.h"
Reid Spencer551ccae2004-09-01 22:55:40 +000018#include "llvm/Config/config.h"
19#include "llvm/Support/CommandLine.h"
20#include "llvm/ADT/StringExtras.h"
Reid Spencer2594c9a2004-08-13 20:21:22 +000021#include <iostream>
Reid Spencer68fb37a2004-08-14 09:37:15 +000022#include <fstream>
Reid Spencer2594c9a2004-08-13 20:21:22 +000023
24using namespace llvm;
25
Reid Spencerb38e4052004-08-20 09:24:07 +000026namespace sys {
27 // From CompilerDriver.cpp (for now)
Reid Spencerf384db32004-08-24 14:03:23 +000028 extern bool FileIsReadable(const std::string& fname);
Reid Spencerb38e4052004-08-20 09:24:07 +000029}
30
Reid Spencer68fb37a2004-08-14 09:37:15 +000031namespace llvm {
Reid Spencerbae68252004-08-19 04:49:47 +000032 ConfigLexerInfo ConfigLexerState;
Reid Spencer68fb37a2004-08-14 09:37:15 +000033 InputProvider* ConfigLexerInput = 0;
Reid Spencer68fb37a2004-08-14 09:37:15 +000034
35 InputProvider::~InputProvider() {}
36 void InputProvider::error(const std::string& msg) {
Reid Spencerbae68252004-08-19 04:49:47 +000037 std::cerr << name << ":" << ConfigLexerState.lineNum << ": Error: " <<
38 msg << "\n";
Reid Spencer68fb37a2004-08-14 09:37:15 +000039 errCount++;
40 }
41
42 void InputProvider::checkErrors() {
43 if (errCount > 0) {
44 std::cerr << name << " had " << errCount << " errors. Terminating.\n";
45 exit(errCount);
46 }
47 }
48
49}
50
Reid Spencer2594c9a2004-08-13 20:21:22 +000051namespace {
52
Reid Spencer68fb37a2004-08-14 09:37:15 +000053 class FileInputProvider : public InputProvider {
54 public:
55 FileInputProvider(const std::string & fname)
56 : InputProvider(fname)
57 , F(fname.c_str()) {
58 ConfigLexerInput = this;
59 }
60 virtual ~FileInputProvider() { F.close(); ConfigLexerInput = 0; }
61 virtual unsigned read(char *buffer, unsigned max_size) {
62 if (F.good()) {
63 F.read(buffer,max_size);
64 if ( F.gcount() ) return F.gcount() - 1;
65 }
66 return 0;
67 }
Reid Spencer2594c9a2004-08-13 20:21:22 +000068
Reid Spencer68fb37a2004-08-14 09:37:15 +000069 bool okay() { return F.good(); }
70 private:
71 std::ifstream F;
72 };
Reid Spencer2594c9a2004-08-13 20:21:22 +000073
Reid Spencer3a9b2222004-10-28 04:04:38 +000074 cl::opt<bool> DumpTokens("dump-tokens", cl::Optional, cl::Hidden,
75 cl::init(false), cl::desc("Dump lexical tokens (debug use only)."));
Reid Spencerbae68252004-08-19 04:49:47 +000076
Reid Spencerbf437722004-08-15 08:19:46 +000077 struct Parser
Reid Spencer68fb37a2004-08-14 09:37:15 +000078 {
Reid Spencerbae68252004-08-19 04:49:47 +000079 Parser() {
80 token = EOFTOK;
81 provider = 0;
82 confDat = 0;
83 ConfigLexerState.lineNum = 1;
84 ConfigLexerState.in_value = false;
85 ConfigLexerState.StringVal.clear();
86 ConfigLexerState.IntegerVal = 0;
87 };
88
Reid Spencerbf437722004-08-15 08:19:46 +000089 ConfigLexerTokens token;
Reid Spencer68fb37a2004-08-14 09:37:15 +000090 InputProvider* provider;
91 CompilerDriver::ConfigData* confDat;
Reid Spencer2594c9a2004-08-13 20:21:22 +000092
Reid Spencer52c2dc12004-08-29 19:26:56 +000093 inline int next() {
Reid Spencerbae68252004-08-19 04:49:47 +000094 token = Configlex();
95 if (DumpTokens)
96 std::cerr << token << "\n";
97 return token;
98 }
Reid Spencer68fb37a2004-08-14 09:37:15 +000099
Reid Spencer52c2dc12004-08-29 19:26:56 +0000100 inline bool next_is_real() {
Reid Spencerbae68252004-08-19 04:49:47 +0000101 next();
Reid Spencer68fb37a2004-08-14 09:37:15 +0000102 return (token != EOLTOK) && (token != ERRORTOK) && (token != 0);
Reid Spencer2594c9a2004-08-13 20:21:22 +0000103 }
104
Reid Spencer52c2dc12004-08-29 19:26:56 +0000105 inline void eatLineRemnant() {
Reid Spencer68fb37a2004-08-14 09:37:15 +0000106 while (next_is_real()) ;
Reid Spencer2594c9a2004-08-13 20:21:22 +0000107 }
108
Reid Spencer68fb37a2004-08-14 09:37:15 +0000109 void error(const std::string& msg, bool skip = true) {
110 provider->error(msg);
111 if (skip)
112 eatLineRemnant();
113 }
Reid Spencer2594c9a2004-08-13 20:21:22 +0000114
Reid Spencer68fb37a2004-08-14 09:37:15 +0000115 std::string parseName() {
116 std::string result;
117 if (next() == EQUALS) {
118 while (next_is_real()) {
119 switch (token ) {
120 case STRING :
121 case OPTION :
Reid Spencerbae68252004-08-19 04:49:47 +0000122 result += ConfigLexerState.StringVal + " ";
Reid Spencer68fb37a2004-08-14 09:37:15 +0000123 break;
124 default:
125 error("Invalid name");
126 break;
127 }
128 }
129 if (result.empty())
130 error("Name exepected");
131 else
132 result.erase(result.size()-1,1);
133 } else
134 error("= expected");
135 return result;
136 }
Reid Spencer2594c9a2004-08-13 20:21:22 +0000137
Reid Spencer68fb37a2004-08-14 09:37:15 +0000138 bool parseBoolean() {
139 bool result = true;
140 if (next() == EQUALS) {
141 if (next() == FALSETOK) {
142 result = false;
143 } else if (token != TRUETOK) {
144 error("Expecting boolean value");
145 return false;
146 }
147 if (next() != EOLTOK && token != 0) {
148 error("Extraneous tokens after boolean");
149 }
150 }
151 else
152 error("Expecting '='");
153 return result;
154 }
Reid Spencer2594c9a2004-08-13 20:21:22 +0000155
Reid Spencerbae68252004-08-19 04:49:47 +0000156 bool parseSubstitution(CompilerDriver::StringVector& optList) {
157 switch (token) {
Reid Spencerf384db32004-08-24 14:03:23 +0000158 case ARGS_SUBST: optList.push_back("%args%"); break;
Reid Spencerca01f9b2004-08-30 06:29:06 +0000159 case DEFS_SUBST: optList.push_back("%defs%"); break;
Reid Spencerca01f9b2004-08-30 06:29:06 +0000160 case IN_SUBST: optList.push_back("%in%"); break;
161 case INCLS_SUBST: optList.push_back("%incls%"); break;
162 case LIBS_SUBST: optList.push_back("%libs%"); break;
163 case OPT_SUBST: optList.push_back("%opt%"); break;
164 case OUT_SUBST: optList.push_back("%out%"); break;
165 case TARGET_SUBST: optList.push_back("%target%"); break;
166 case STATS_SUBST: optList.push_back("%stats%"); break;
167 case TIME_SUBST: optList.push_back("%time%"); break;
Reid Spencer52c2dc12004-08-29 19:26:56 +0000168 case VERBOSE_SUBST: optList.push_back("%verbose%"); break;
Reid Spencerbae68252004-08-19 04:49:47 +0000169 default:
170 return false;
Reid Spencer68fb37a2004-08-14 09:37:15 +0000171 }
Reid Spencerbae68252004-08-19 04:49:47 +0000172 return true;
173 }
174
175 void parseOptionList(CompilerDriver::StringVector& optList ) {
176 if (next() == EQUALS) {
177 while (next_is_real()) {
178 if (token == STRING || token == OPTION)
179 optList.push_back(ConfigLexerState.StringVal);
180 else if (!parseSubstitution(optList)) {
181 error("Expecting a program argument or substitution", false);
182 break;
183 }
184 }
185 } else
186 error("Expecting '='");
Reid Spencerbf437722004-08-15 08:19:46 +0000187 }
188
Reid Spencer59a745a2004-08-22 18:03:25 +0000189 void parseVersion() {
190 if (next() == EQUALS) {
191 while (next_is_real()) {
192 if (token == STRING || token == OPTION)
193 confDat->version = ConfigLexerState.StringVal;
194 else
195 error("Expecting a version string");
196 }
197 } else
198 error("Expecting '='");
199 }
200
Reid Spencerbf437722004-08-15 08:19:46 +0000201 void parseLang() {
202 switch (next() ) {
203 case NAME:
204 confDat->langName = parseName();
205 break;
206 case OPT1:
207 parseOptionList(confDat->opts[CompilerDriver::OPT_FAST_COMPILE]);
208 break;
209 case OPT2:
210 parseOptionList(confDat->opts[CompilerDriver::OPT_SIMPLE]);
211 break;
212 case OPT3:
213 parseOptionList(confDat->opts[CompilerDriver::OPT_AGGRESSIVE]);
214 break;
215 case OPT4:
216 parseOptionList(confDat->opts[CompilerDriver::OPT_LINK_TIME]);
217 break;
218 case OPT5:
219 parseOptionList(
220 confDat->opts[CompilerDriver::OPT_AGGRESSIVE_LINK_TIME]);
221 break;
222 default:
223 error("Expecting 'name' or 'optN' after 'lang.'");
224 break;
Reid Spencer68fb37a2004-08-14 09:37:15 +0000225 }
226 }
Reid Spencer2594c9a2004-08-13 20:21:22 +0000227
Reid Spencer68fb37a2004-08-14 09:37:15 +0000228 void parseCommand(CompilerDriver::Action& action) {
229 if (next() == EQUALS) {
Reid Spencerbf437722004-08-15 08:19:46 +0000230 if (next() == EOLTOK) {
Reid Spencer68fb37a2004-08-14 09:37:15 +0000231 // no value (valid)
232 action.program.clear();
233 action.args.clear();
Reid Spencer68fb37a2004-08-14 09:37:15 +0000234 } else {
235 if (token == STRING || token == OPTION) {
Reid Spencer07adb282004-11-05 22:15:36 +0000236 action.program.setFile(ConfigLexerState.StringVal);
Reid Spencer2594c9a2004-08-13 20:21:22 +0000237 } else {
Reid Spencer68fb37a2004-08-14 09:37:15 +0000238 error("Expecting a program name");
239 }
240 while (next_is_real()) {
Reid Spencerbf437722004-08-15 08:19:46 +0000241 if (token == STRING || token == OPTION) {
Reid Spencerbae68252004-08-19 04:49:47 +0000242 action.args.push_back(ConfigLexerState.StringVal);
243 } else if (!parseSubstitution(action.args)) {
244 error("Expecting a program argument or substitution", false);
Reid Spencerbf437722004-08-15 08:19:46 +0000245 break;
246 }
Reid Spencer2594c9a2004-08-13 20:21:22 +0000247 }
248 }
Reid Spencer68fb37a2004-08-14 09:37:15 +0000249 }
Reid Spencer2594c9a2004-08-13 20:21:22 +0000250 }
Reid Spencer68fb37a2004-08-14 09:37:15 +0000251
Reid Spencerbf437722004-08-15 08:19:46 +0000252 void parsePreprocessor() {
253 switch (next()) {
254 case COMMAND:
255 parseCommand(confDat->PreProcessor);
256 break;
257 case REQUIRED:
258 if (parseBoolean())
259 confDat->PreProcessor.set(CompilerDriver::REQUIRED_FLAG);
260 else
261 confDat->PreProcessor.clear(CompilerDriver::REQUIRED_FLAG);
262 break;
263 default:
Reid Spencerf384db32004-08-24 14:03:23 +0000264 error("Expecting 'command' or 'required' but found '" +
265 ConfigLexerState.StringVal);
Reid Spencerbf437722004-08-15 08:19:46 +0000266 break;
Reid Spencer68fb37a2004-08-14 09:37:15 +0000267 }
Reid Spencer68fb37a2004-08-14 09:37:15 +0000268 }
269
Reid Spencerf384db32004-08-24 14:03:23 +0000270 bool parseOutputFlag() {
271 if (next() == EQUALS) {
272 if (next() == ASSEMBLY) {
273 return true;
274 } else if (token == BYTECODE) {
275 return false;
276 } else {
277 error("Expecting output type value");
278 return false;
279 }
280 if (next() != EOLTOK && token != 0) {
281 error("Extraneous tokens after output value");
282 }
283 }
284 else
285 error("Expecting '='");
286 return false;
287 }
288
Reid Spencer68fb37a2004-08-14 09:37:15 +0000289 void parseTranslator() {
Reid Spencerbf437722004-08-15 08:19:46 +0000290 switch (next()) {
291 case COMMAND:
292 parseCommand(confDat->Translator);
293 break;
294 case REQUIRED:
295 if (parseBoolean())
296 confDat->Translator.set(CompilerDriver::REQUIRED_FLAG);
297 else
298 confDat->Translator.clear(CompilerDriver::REQUIRED_FLAG);
299 break;
300 case PREPROCESSES:
301 if (parseBoolean())
302 confDat->Translator.set(CompilerDriver::PREPROCESSES_FLAG);
303 else
304 confDat->Translator.clear(CompilerDriver::PREPROCESSES_FLAG);
305 break;
Reid Spencerf384db32004-08-24 14:03:23 +0000306 case OUTPUT:
307 if (parseOutputFlag())
Reid Spencerbae68252004-08-19 04:49:47 +0000308 confDat->Translator.set(CompilerDriver::OUTPUT_IS_ASM_FLAG);
Reid Spencerbf437722004-08-15 08:19:46 +0000309 else
Reid Spencerbae68252004-08-19 04:49:47 +0000310 confDat->Translator.clear(CompilerDriver::OUTPUT_IS_ASM_FLAG);
Reid Spencerbf437722004-08-15 08:19:46 +0000311 break;
Reid Spencerbae68252004-08-19 04:49:47 +0000312
Reid Spencerbf437722004-08-15 08:19:46 +0000313 default:
Reid Spencerf384db32004-08-24 14:03:23 +0000314 error("Expecting 'command', 'required', 'preprocesses', or "
315 "'output' but found '" + ConfigLexerState.StringVal +
316 "' instead");
Reid Spencerbf437722004-08-15 08:19:46 +0000317 break;
Reid Spencer68fb37a2004-08-14 09:37:15 +0000318 }
Reid Spencer68fb37a2004-08-14 09:37:15 +0000319 }
320
321 void parseOptimizer() {
Reid Spencerbf437722004-08-15 08:19:46 +0000322 switch (next()) {
323 case COMMAND:
324 parseCommand(confDat->Optimizer);
325 break;
Reid Spencerbae68252004-08-19 04:49:47 +0000326 case PREPROCESSES:
327 if (parseBoolean())
328 confDat->Optimizer.set(CompilerDriver::PREPROCESSES_FLAG);
329 else
330 confDat->Optimizer.clear(CompilerDriver::PREPROCESSES_FLAG);
331 break;
332 case TRANSLATES:
333 if (parseBoolean())
334 confDat->Optimizer.set(CompilerDriver::TRANSLATES_FLAG);
335 else
336 confDat->Optimizer.clear(CompilerDriver::TRANSLATES_FLAG);
337 break;
Reid Spencerf384db32004-08-24 14:03:23 +0000338 case REQUIRED:
Reid Spencerbf437722004-08-15 08:19:46 +0000339 if (parseBoolean())
Reid Spencerf384db32004-08-24 14:03:23 +0000340 confDat->Optimizer.set(CompilerDriver::REQUIRED_FLAG);
Reid Spencerbf437722004-08-15 08:19:46 +0000341 else
Reid Spencerf384db32004-08-24 14:03:23 +0000342 confDat->Optimizer.clear(CompilerDriver::REQUIRED_FLAG);
Reid Spencerbf437722004-08-15 08:19:46 +0000343 break;
Reid Spencerf384db32004-08-24 14:03:23 +0000344 case OUTPUT:
345 if (parseOutputFlag())
Reid Spencerbae68252004-08-19 04:49:47 +0000346 confDat->Translator.set(CompilerDriver::OUTPUT_IS_ASM_FLAG);
Reid Spencerbf437722004-08-15 08:19:46 +0000347 else
Reid Spencerbae68252004-08-19 04:49:47 +0000348 confDat->Translator.clear(CompilerDriver::OUTPUT_IS_ASM_FLAG);
Reid Spencerbf437722004-08-15 08:19:46 +0000349 break;
350 default:
Reid Spencer3a9b2222004-10-28 04:04:38 +0000351 error(std::string("Expecting 'command', 'preprocesses', "
352 "'translates' or 'output' but found '") +
Reid Spencerf384db32004-08-24 14:03:23 +0000353 ConfigLexerState.StringVal + "' instead");
Reid Spencerbf437722004-08-15 08:19:46 +0000354 break;
Reid Spencer68fb37a2004-08-14 09:37:15 +0000355 }
Reid Spencer68fb37a2004-08-14 09:37:15 +0000356 }
357
358 void parseAssembler() {
Reid Spencerbf437722004-08-15 08:19:46 +0000359 switch(next()) {
360 case COMMAND:
361 parseCommand(confDat->Assembler);
362 break;
363 default:
364 error("Expecting 'command'");
365 break;
Reid Spencer68fb37a2004-08-14 09:37:15 +0000366 }
Reid Spencer68fb37a2004-08-14 09:37:15 +0000367 }
368
369 void parseLinker() {
Reid Spencerbf437722004-08-15 08:19:46 +0000370 switch(next()) {
Reid Spencerf384db32004-08-24 14:03:23 +0000371 case LIBS:
372 break; //FIXME
373 case LIBPATHS:
374 break; //FIXME
Reid Spencerbf437722004-08-15 08:19:46 +0000375 default:
Reid Spencerf384db32004-08-24 14:03:23 +0000376 error("Expecting 'libs' or 'libpaths'");
Reid Spencerbf437722004-08-15 08:19:46 +0000377 break;
Reid Spencer68fb37a2004-08-14 09:37:15 +0000378 }
Reid Spencer68fb37a2004-08-14 09:37:15 +0000379 }
380
381 void parseAssignment() {
382 switch (token) {
Reid Spencer3a9b2222004-10-28 04:04:38 +0000383 case VERSION_TOK: parseVersion(); break;
Reid Spencerbf437722004-08-15 08:19:46 +0000384 case LANG: parseLang(); break;
385 case PREPROCESSOR: parsePreprocessor(); break;
386 case TRANSLATOR: parseTranslator(); break;
387 case OPTIMIZER: parseOptimizer(); break;
388 case ASSEMBLER: parseAssembler(); break;
389 case LINKER: parseLinker(); break;
Reid Spencer68fb37a2004-08-14 09:37:15 +0000390 case EOLTOK: break; // just ignore
391 case ERRORTOK:
392 default:
Reid Spencerbf437722004-08-15 08:19:46 +0000393 error("Invalid top level configuration item");
394 break;
Reid Spencer68fb37a2004-08-14 09:37:15 +0000395 }
396 }
397
398 void parseFile() {
Reid Spencerbf437722004-08-15 08:19:46 +0000399 while ( next() != EOFTOK ) {
400 if (token == ERRORTOK)
401 error("Invalid token");
402 else if (token != EOLTOK)
403 parseAssignment();
Reid Spencer68fb37a2004-08-14 09:37:15 +0000404 }
405 provider->checkErrors();
406 }
407 };
408
Reid Spencer3a9b2222004-10-28 04:04:38 +0000409void
410ParseConfigData(InputProvider& provider, CompilerDriver::ConfigData& confDat) {
411 Parser p;
412 p.token = EOFTOK;
413 p.provider = &provider;
414 p.confDat = &confDat;
415 p.parseFile();
Reid Spencer2594c9a2004-08-13 20:21:22 +0000416 }
Reid Spencer3a9b2222004-10-28 04:04:38 +0000417
Reid Spencer2594c9a2004-08-13 20:21:22 +0000418}
419
420CompilerDriver::ConfigData*
Reid Spencer68fb37a2004-08-14 09:37:15 +0000421LLVMC_ConfigDataProvider::ReadConfigData(const std::string& ftype) {
422 CompilerDriver::ConfigData* result = 0;
Reid Spencer52c2dc12004-08-29 19:26:56 +0000423 sys::Path confFile;
Reid Spencer07adb282004-11-05 22:15:36 +0000424 if (configDir.isEmpty()) {
Reid Spencerb38e4052004-08-20 09:24:07 +0000425 // Try the environment variable
426 const char* conf = getenv("LLVM_CONFIG_DIR");
427 if (conf) {
Reid Spencer07adb282004-11-05 22:15:36 +0000428 confFile.setDirectory(conf);
429 confFile.appendFile(ftype);
Reid Spencer52c2dc12004-08-29 19:26:56 +0000430 if (!confFile.readable())
Reid Spencerca01f9b2004-08-30 06:29:06 +0000431 throw std::string("Configuration file for '") + ftype +
432 "' is not available.";
Reid Spencerb38e4052004-08-20 09:24:07 +0000433 } else {
434 // Try the user's home directory
Reid Spencer52c2dc12004-08-29 19:26:56 +0000435 confFile = sys::Path::GetUserHomeDirectory();
Reid Spencer07adb282004-11-05 22:15:36 +0000436 if (!confFile.isEmpty()) {
437 confFile.appendDirectory(".llvm");
438 confFile.appendDirectory("etc");
439 confFile.appendFile(ftype);
Reid Spencer52c2dc12004-08-29 19:26:56 +0000440 if (!confFile.readable())
441 confFile.clear();
442 }
Reid Spencer07adb282004-11-05 22:15:36 +0000443 if (!confFile.isEmpty()) {
Reid Spencer52c2dc12004-08-29 19:26:56 +0000444 // Okay, try the LLVM installation directory
445 confFile = sys::Path::GetLLVMConfigDir();
Reid Spencer07adb282004-11-05 22:15:36 +0000446 confFile.appendFile(ftype);
Reid Spencer52c2dc12004-08-29 19:26:56 +0000447 if (!confFile.readable()) {
448 // Okay, try the "standard" place
449 confFile = sys::Path::GetLLVMDefaultConfigDir();
Reid Spencer07adb282004-11-05 22:15:36 +0000450 confFile.appendFile(ftype);
Reid Spencer52c2dc12004-08-29 19:26:56 +0000451 if (!confFile.readable()) {
Reid Spencerca01f9b2004-08-30 06:29:06 +0000452 throw std::string("Configuration file for '") + ftype +
453 "' is not available.";
Reid Spencerb38e4052004-08-20 09:24:07 +0000454 }
455 }
456 }
Reid Spencer68fb37a2004-08-14 09:37:15 +0000457 }
458 } else {
Reid Spencer52c2dc12004-08-29 19:26:56 +0000459 confFile = configDir;
Reid Spencer07adb282004-11-05 22:15:36 +0000460 confFile.appendFile(ftype);
Reid Spencer52c2dc12004-08-29 19:26:56 +0000461 if (!confFile.readable())
Reid Spencerca01f9b2004-08-30 06:29:06 +0000462 throw std::string("Configuration file for '") + ftype +
463 "' is not available.";
Reid Spencer2594c9a2004-08-13 20:21:22 +0000464 }
Reid Spencer52c2dc12004-08-29 19:26:56 +0000465 FileInputProvider fip( confFile.get() );
Reid Spencerb38e4052004-08-20 09:24:07 +0000466 if (!fip.okay()) {
Reid Spencerca01f9b2004-08-30 06:29:06 +0000467 throw std::string("Configuration file for '") + ftype +
468 "' is not available.";
Reid Spencerb38e4052004-08-20 09:24:07 +0000469 }
470 result = new CompilerDriver::ConfigData();
471 ParseConfigData(fip,*result);
Reid Spencer68fb37a2004-08-14 09:37:15 +0000472 return result;
Reid Spencer2594c9a2004-08-13 20:21:22 +0000473}
474
Reid Spencer2594c9a2004-08-13 20:21:22 +0000475LLVMC_ConfigDataProvider::~LLVMC_ConfigDataProvider()
476{
477 ConfigDataMap::iterator cIt = Configurations.begin();
478 while (cIt != Configurations.end()) {
479 CompilerDriver::ConfigData* cd = cIt->second;
480 ++cIt;
481 delete cd;
482 }
483 Configurations.clear();
484}
485
486CompilerDriver::ConfigData*
487LLVMC_ConfigDataProvider::ProvideConfigData(const std::string& filetype) {
488 CompilerDriver::ConfigData* result = 0;
489 if (!Configurations.empty()) {
490 ConfigDataMap::iterator cIt = Configurations.find(filetype);
491 if ( cIt != Configurations.end() ) {
492 // We found one in the case, return it.
493 result = cIt->second;
494 }
495 }
496 if (result == 0) {
497 // The configuration data doesn't exist, we have to go read it.
498 result = ReadConfigData(filetype);
499 // If we got one, cache it
Reid Spencer52c2dc12004-08-29 19:26:56 +0000500 if (result != 0)
Reid Spencer2594c9a2004-08-13 20:21:22 +0000501 Configurations.insert(std::make_pair(filetype,result));
502 }
503 return result; // Might return 0
504}
505
506// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab