//===- Configuration.cpp - Configuration Data Mgmt --------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by Reid Spencer and is distributed under the
// University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the parsing of configuration files for the LLVM Compiler
// Driver (llvmc).
//
//===------------------------------------------------------------------------===

#include "Configuration.h"
#include "ConfigLexer.h"
#include "CompilerDriver.h"
#include "llvm/Config/config.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/ADT/StringExtras.h"
#include <iostream>
#include <fstream>

using namespace llvm;

namespace sys {
  // From CompilerDriver.cpp (for now)
  extern bool FileIsReadable(const std::string& fname);
}

namespace llvm {
  ConfigLexerInfo ConfigLexerState;
  InputProvider* ConfigLexerInput = 0;

  InputProvider::~InputProvider() {}
  void InputProvider::error(const std::string& msg) {
    std::cerr << name << ":" << ConfigLexerState.lineNum << ": Error: " <<
      msg << "\n";
    errCount++;
  }

  void InputProvider::checkErrors() {
    if (errCount > 0) {
      std::cerr << name << " had " << errCount << " errors. Terminating.\n";
      exit(errCount);
    }
  }

}

namespace {

  class FileInputProvider : public InputProvider {
    public:
      FileInputProvider(const std::string & fname)
        : InputProvider(fname)
        , F(fname.c_str()) {
        ConfigLexerInput = this;
      }
      virtual ~FileInputProvider() { F.close(); ConfigLexerInput = 0; }
      virtual unsigned read(char *buffer, unsigned max_size) {
        if (F.good()) {
          F.read(buffer,max_size);
          if ( F.gcount() ) return F.gcount() - 1;
        }
        return 0;
      }

      bool okay() { return F.good(); }
    private:
      std::ifstream F;
  };

  cl::opt<bool> DumpTokens("dump-tokens", cl::Optional, cl::Hidden,
    cl::init(false), cl::desc("Dump lexical tokens (debug use only)."));

  struct Parser
  {
    Parser() {
      token = EOFTOK;
      provider = 0;
      confDat = 0;
      ConfigLexerState.lineNum = 1;
      ConfigLexerState.in_value = false;
      ConfigLexerState.StringVal.clear();
      ConfigLexerState.IntegerVal = 0;
    };

    ConfigLexerTokens token;
    InputProvider* provider;
    CompilerDriver::ConfigData* confDat;

    inline int next() {
      token = Configlex();
      if (DumpTokens)
        std::cerr << token << "\n";
      return token;
    }

    inline bool next_is_real() {
      next();
      return (token != EOLTOK) && (token != ERRORTOK) && (token != 0);
    }

    inline void eatLineRemnant() {
      while (next_is_real()) ;
    }

    void error(const std::string& msg, bool skip = true) {
      provider->error(msg);
      if (skip)
        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) {
        if (parseCompleteItem(result))
          eatLineRemnant();
        if (result.empty())
          error("Name exepected");
      } else
        error("Expecting '='");
      return result;
    }

    bool parseBoolean() {
      bool result = true;
      if (next() == EQUALS) {
        if (next() == SPACE)
          next();
        if (token == FALSETOK) {
          result = false;
        } else if (token != TRUETOK) {
          error("Expecting boolean value");
          return false;
        }
        if (next() != EOLTOK && token != 0) {
          error("Extraneous tokens after boolean");
        }
      }
      else
        error("Expecting '='");
      return result;
    }

    bool parseSubstitution(CompilerDriver::StringVector& optList) {
      switch (token) {
        case ARGS_SUBST:        optList.push_back("%args%"); break;
        case DEFS_SUBST:        optList.push_back("%defs%"); break;
        case IN_SUBST:          optList.push_back("%in%"); break;
        case INCLS_SUBST:       optList.push_back("%incls%"); break;
        case LIBS_SUBST:        optList.push_back("%libs%"); break;
        case OPT_SUBST:         optList.push_back("%opt%"); break;
        case OUT_SUBST:         optList.push_back("%out%"); break;
        case TARGET_SUBST:      optList.push_back("%target%"); break;
        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;
      }
      return true;
    }

    void parseOptionList(CompilerDriver::StringVector& optList ) {
      if (next() == EQUALS) {
        while (next_is_real()) {
          if (token == STRING || token == OPTION)
            optList.push_back(ConfigLexerState.StringVal);
          else if (!parseSubstitution(optList)) {
            error("Expecting a program argument or substitution", false);
            break;
          }
        }
      } else
        error("Expecting '='");
    }

    void parseVersion() {
      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;
        case OPT1:
          parseOptionList(confDat->opts[CompilerDriver::OPT_FAST_COMPILE]);
          break;
        case OPT2:
          parseOptionList(confDat->opts[CompilerDriver::OPT_SIMPLE]);
          break;
        case OPT3:
          parseOptionList(confDat->opts[CompilerDriver::OPT_AGGRESSIVE]);
          break;
        case OPT4:
          parseOptionList(confDat->opts[CompilerDriver::OPT_LINK_TIME]);
          break;
        case OPT5:
          parseOptionList(
            confDat->opts[CompilerDriver::OPT_AGGRESSIVE_LINK_TIME]);
          break;
        default:
          error("Expecting 'name' or 'optN' after 'lang.'");
          break;
      }
    }

    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)
        error("Expecting '='");
      switch (next()) {
        case EOLTOK:
          // no value (valid)
          action.program.clear();
          action.args.clear();
          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()) {
            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;
            }
          }
        }
      }
    }

    void parsePreprocessor() {
      if (next() != SEPARATOR)
        error("Expecting '.'");
      switch (next()) {
        case COMMAND:
          parseCommand(confDat->PreProcessor);
          break;
        case REQUIRED:
          if (parseBoolean())
            confDat->PreProcessor.set(CompilerDriver::REQUIRED_FLAG);
          else
            confDat->PreProcessor.clear(CompilerDriver::REQUIRED_FLAG);
          break;
        default:
          error("Expecting 'command' or 'required' but found '" +
              ConfigLexerState.StringVal);
          break;
      }
    }

    bool parseOutputFlag() {
      if (next() == EQUALS) {
        if (next() == SPACE)
          next();
        if (token == ASSEMBLY) {
          return true;
        } else if (token == BYTECODE) {
          return false;
        } else {
          error("Expecting output type value");
          return false;
        }
        if (next() != EOLTOK && token != 0) {
          error("Extraneous tokens after output value");
        }
      }
      else
        error("Expecting '='");
      return false;
    }

    void parseTranslator() {
      if (next() != SEPARATOR)
        error("Expecting '.'");
      switch (next()) {
        case COMMAND:
          parseCommand(confDat->Translator);
          break;
        case REQUIRED:
          if (parseBoolean())
            confDat->Translator.set(CompilerDriver::REQUIRED_FLAG);
          else
            confDat->Translator.clear(CompilerDriver::REQUIRED_FLAG);
          break;
        case PREPROCESSES:
          if (parseBoolean())
            confDat->Translator.set(CompilerDriver::PREPROCESSES_FLAG);
          else
            confDat->Translator.clear(CompilerDriver::PREPROCESSES_FLAG);
          break;
        case OUTPUT:
          if (parseOutputFlag())
            confDat->Translator.set(CompilerDriver::OUTPUT_IS_ASM_FLAG);
          else
            confDat->Translator.clear(CompilerDriver::OUTPUT_IS_ASM_FLAG);
          break;

        default:
          error("Expecting 'command', 'required', 'preprocesses', or "
                "'output' but found '" + ConfigLexerState.StringVal +
                "' instead");
          break;
      }
    }

    void parseOptimizer() {
      if (next() != SEPARATOR)
        error("Expecting '.'");
      switch (next()) {
        case COMMAND:
          parseCommand(confDat->Optimizer);
          break;
        case PREPROCESSES:
          if (parseBoolean())
            confDat->Optimizer.set(CompilerDriver::PREPROCESSES_FLAG);
          else
            confDat->Optimizer.clear(CompilerDriver::PREPROCESSES_FLAG);
          break;
        case TRANSLATES:
          if (parseBoolean())
            confDat->Optimizer.set(CompilerDriver::TRANSLATES_FLAG);
          else
            confDat->Optimizer.clear(CompilerDriver::TRANSLATES_FLAG);
          break;
        case REQUIRED:
          if (parseBoolean())
            confDat->Optimizer.set(CompilerDriver::REQUIRED_FLAG);
          else
            confDat->Optimizer.clear(CompilerDriver::REQUIRED_FLAG);
          break;
        case OUTPUT:
          if (parseOutputFlag())
            confDat->Translator.set(CompilerDriver::OUTPUT_IS_ASM_FLAG);
          else
            confDat->Translator.clear(CompilerDriver::OUTPUT_IS_ASM_FLAG);
          break;
        default:
          error(std::string("Expecting 'command', 'preprocesses', "
              "'translates' or 'output' but found '") +
              ConfigLexerState.StringVal + "' instead");
          break;
      }
    }

    void parseAssembler() {
      if (next() != SEPARATOR)
        error("Expecting '.'");
      switch(next()) {
        case COMMAND:
          parseCommand(confDat->Assembler);
          break;
        default:
          error("Expecting 'command'");
          break;
      }
    }

    void parseLinker() {
      if (next() != SEPARATOR)
        error("Expecting '.'");
      switch(next()) {
        case LIBS:
          break; //FIXME
        case LIBPATHS:
          break; //FIXME
        default:
          error("Expecting 'libs' or 'libpaths'");
          break;
      }
    }

    void parseAssignment() {
      switch (token) {
        case VERSION_TOK:   parseVersion(); break;
        case LANG:          parseLang(); break;
        case PREPROCESSOR:  parsePreprocessor(); break;
        case TRANSLATOR:    parseTranslator(); break;
        case OPTIMIZER:     parseOptimizer(); break;
        case ASSEMBLER:     parseAssembler(); break;
        case LINKER:        parseLinker(); break;
        case EOLTOK:        break; // just ignore
        case ERRORTOK:
        default:
          error("Invalid top level configuration item");
          break;
      }
    }

    void parseFile() {
      while ( next() != EOFTOK ) {
        if (token == ERRORTOK)
          error("Invalid token");
        else if (token != EOLTOK)
          parseAssignment();
      }
      provider->checkErrors();
    }
  };

void
ParseConfigData(InputProvider& provider, CompilerDriver::ConfigData& confDat) {
  Parser p;
  p.token = EOFTOK;
  p.provider = &provider;
  p.confDat = &confDat;
  p.parseFile();
  }

}

CompilerDriver::ConfigData*
LLVMC_ConfigDataProvider::ReadConfigData(const std::string& ftype) {
  CompilerDriver::ConfigData* result = 0;
  sys::Path confFile;
  if (configDir.isEmpty()) {
    // Try the environment variable
    const char* conf = getenv("LLVM_CONFIG_DIR");
    if (conf) {
      confFile.setDirectory(conf);
      confFile.appendFile(ftype);
      if (!confFile.readable())
        throw std::string("Configuration file for '") + ftype +
                          "' is not available.";
    } else {
      // Try the user's home directory
      confFile = sys::Path::GetUserHomeDirectory();
      if (!confFile.isEmpty()) {
        confFile.appendDirectory(".llvm");
        confFile.appendDirectory("etc");
        confFile.appendFile(ftype);
        if (!confFile.readable())
          confFile.clear();
      }
      if (!confFile.isEmpty()) {
        // Okay, try the LLVM installation directory
        confFile = sys::Path::GetLLVMConfigDir();
        confFile.appendFile(ftype);
        if (!confFile.readable()) {
          // Okay, try the "standard" place
          confFile = sys::Path::GetLLVMDefaultConfigDir();
          confFile.appendFile(ftype);
          if (!confFile.readable()) {
            throw std::string("Configuration file for '") + ftype +
                              "' is not available.";
          }
        }
      }
    }
  } else {
    confFile = configDir;
    confFile.appendFile(ftype);
    if (!confFile.readable())
      throw std::string("Configuration file for '") + ftype +
                        "' is not available.";
  }
  FileInputProvider fip( confFile.toString() );
  if (!fip.okay()) {
    throw std::string("Configuration file for '") + ftype +
                      "' is not available.";
  }
  result = new CompilerDriver::ConfigData();
  ParseConfigData(fip,*result);
  return result;
}

LLVMC_ConfigDataProvider::~LLVMC_ConfigDataProvider()
{
  ConfigDataMap::iterator cIt = Configurations.begin();
  while (cIt != Configurations.end()) {
    CompilerDriver::ConfigData* cd = cIt->second;
    ++cIt;
    delete cd;
  }
  Configurations.clear();
}

CompilerDriver::ConfigData*
LLVMC_ConfigDataProvider::ProvideConfigData(const std::string& filetype) {
  CompilerDriver::ConfigData* result = 0;
  if (!Configurations.empty()) {
    ConfigDataMap::iterator cIt = Configurations.find(filetype);
    if ( cIt != Configurations.end() ) {
      // We found one in the case, return it.
      result = cIt->second;
    }
  }
  if (result == 0) {
    // The configuration data doesn't exist, we have to go read it.
    result = ReadConfigData(filetype);
    // If we got one, cache it
    if (result != 0)
      Configurations.insert(std::make_pair(filetype,result));
  }
  return result; // Might return 0
}

// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab
