From e9564cedb4b5d3940187ee1056e2a1f07525da47 Mon Sep 17 00:00:00 2001 From: Reid Spencer Date: Tue, 23 Nov 2004 23:37:26 +0000 Subject: [PATCH] Make various adjustments to parsing so that the separator character doesn't terminate options or paths, so that SPACE tokens legally separate options on a command line, and so that the lang.libs paths are parsed properly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@18184 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvmc/Configuration.cpp | 192 +++++++++++++++++++++++++++------- 1 file changed, 156 insertions(+), 36 deletions(-) diff --git a/tools/llvmc/Configuration.cpp b/tools/llvmc/Configuration.cpp index 01611ad3356..f0e98355272 100644 --- a/tools/llvmc/Configuration.cpp +++ b/tools/llvmc/Configuration.cpp @@ -112,33 +112,44 @@ namespace { eatLineRemnant(); } + bool parseCompleteItem(std::string& result) { + result.clear(); + while (next_is_real()) { + switch (token ) { + case STRING : + case OPTION : + result += ConfigLexerState.StringVal; + break; + case SEPARATOR: + result += "."; + break; + case SPACE: + return true; + default: + return false; + } + } + return false; + } + std::string parseName() { std::string result; if (next() == EQUALS) { - while (next_is_real()) { - switch (token ) { - case STRING : - case OPTION : - result += ConfigLexerState.StringVal + " "; - break; - default: - error("Invalid name"); - break; - } - } + if (parseCompleteItem(result)) + eatLineRemnant(); if (result.empty()) error("Name exepected"); - else - result.erase(result.size()-1,1); } else - error("= expected"); + error("Expecting '='"); return result; } bool parseBoolean() { bool result = true; if (next() == EQUALS) { - if (next() == FALSETOK) { + if (next() == SPACE) + next(); + if (token == FALSETOK) { result = false; } else if (token != TRUETOK) { error("Expecting boolean value"); @@ -166,6 +177,9 @@ namespace { case STATS_SUBST: optList.push_back("%stats%"); break; case TIME_SUBST: optList.push_back("%time%"); break; case VERBOSE_SUBST: optList.push_back("%verbose%"); break; + case FOPTS_SUBST: optList.push_back("%fOpts%"); break; + case MOPTS_SUBST: optList.push_back("%Mopts%"); break; + case WOPTS_SUBST: optList.push_back("%Wopts%"); break; default: return false; } @@ -187,19 +201,34 @@ namespace { } void parseVersion() { - if (next() == EQUALS) { - while (next_is_real()) { - if (token == STRING || token == OPTION) - confDat->version = ConfigLexerState.StringVal; - else - error("Expecting a version string"); - } - } else + if (next() != EQUALS) error("Expecting '='"); + while (next_is_real()) { + if (token == STRING || token == OPTION) + confDat->version = ConfigLexerState.StringVal; + else + error("Expecting a version string"); + } + } + + void parseLibs() { + if (next() != EQUALS) + error("Expecting '='"); + std::string lib; + while (parseCompleteItem(lib)) { + if (!lib.empty()) { + confDat->libpaths.push_back(lib); + } + } } void parseLang() { + if (next() != SEPARATOR) + error("Expecting '.'"); switch (next() ) { + case LIBS: + parseLibs(); + break; case NAME: confDat->langName = parseName(); break; @@ -225,24 +254,103 @@ namespace { } } + bool parseProgramName(std::string& str) { + str.clear(); + do { + switch (token) { + case OPTION: + case STRING: + case ARGS_SUBST: + case DEFS_SUBST: + case IN_SUBST: + case INCLS_SUBST: + case LIBS_SUBST: + case OPT_SUBST: + case OUT_SUBST: + case STATS_SUBST: + case TARGET_SUBST: + case TIME_SUBST: + case VERBOSE_SUBST: + case FOPTS_SUBST: + case MOPTS_SUBST: + case WOPTS_SUBST: + str += ConfigLexerState.StringVal; + break; + case SEPARATOR: + str += "."; + break; + case ASSEMBLY: + str += "assembly"; + break; + case BYTECODE: + str += "bytecode"; + break; + case TRUETOK: + str += "true"; + break; + case FALSETOK: + str += "false"; + break; + default: + break; + } + next(); + } while (token != SPACE && token != EOFTOK && token != EOLTOK && + token != ERRORTOK); + return !str.empty(); + } + void parseCommand(CompilerDriver::Action& action) { - if (next() == EQUALS) { - if (next() == EOLTOK) { + if (next() != EQUALS) + error("Expecting '='"); + switch (next()) { + case EOLTOK: // no value (valid) action.program.clear(); action.args.clear(); - } else { - if (token == STRING || token == OPTION) { - action.program.setFile(ConfigLexerState.StringVal); - } else { + break; + case SPACE: + next(); + /* FALL THROUGH */ + default: + { + std::string progname; + if (parseProgramName(progname)) + action.program.setFile(progname); + else error("Expecting a program name"); - } + + // Get the options + std::string anOption; while (next_is_real()) { - if (token == STRING || token == OPTION) { - action.args.push_back(ConfigLexerState.StringVal); - } else if (!parseSubstitution(action.args)) { - error("Expecting a program argument or substitution", false); - break; + switch (token) { + case STRING: + case OPTION: + anOption += ConfigLexerState.StringVal; + break; + case ASSEMBLY: + anOption += "assembly"; + break; + case BYTECODE: + anOption += "bytecode"; + break; + case TRUETOK: + anOption += "true"; + break; + case FALSETOK: + anOption += "false"; + break; + case SEPARATOR: + anOption += "."; + break; + case SPACE: + action.args.push_back(anOption); + anOption.clear(); + break; + default: + if (!parseSubstitution(action.args)) + error("Expecting a program argument or substitution", false); + break; } } } @@ -250,6 +358,8 @@ namespace { } void parsePreprocessor() { + if (next() != SEPARATOR) + error("Expecting '.'"); switch (next()) { case COMMAND: parseCommand(confDat->PreProcessor); @@ -269,7 +379,9 @@ namespace { bool parseOutputFlag() { if (next() == EQUALS) { - if (next() == ASSEMBLY) { + if (next() == SPACE) + next(); + if (token == ASSEMBLY) { return true; } else if (token == BYTECODE) { return false; @@ -287,6 +399,8 @@ namespace { } void parseTranslator() { + if (next() != SEPARATOR) + error("Expecting '.'"); switch (next()) { case COMMAND: parseCommand(confDat->Translator); @@ -319,6 +433,8 @@ namespace { } void parseOptimizer() { + if (next() != SEPARATOR) + error("Expecting '.'"); switch (next()) { case COMMAND: parseCommand(confDat->Optimizer); @@ -356,6 +472,8 @@ namespace { } void parseAssembler() { + if (next() != SEPARATOR) + error("Expecting '.'"); switch(next()) { case COMMAND: parseCommand(confDat->Assembler); @@ -367,6 +485,8 @@ namespace { } void parseLinker() { + if (next() != SEPARATOR) + error("Expecting '.'"); switch(next()) { case LIBS: break; //FIXME -- 2.34.1