/*
 Copyright 2019 Alain Dargelas
 
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at
 
 http://www.apache.org/licenses/LICENSE-2.0
 
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

/* 
 * File:   PreprocessFile.cpp
 * Author: alain
 * 
 * Created on February 24, 2017, 9:38 PM
 */
#include "SymbolTable.h"
#include "../CommandLine/CommandLineParser.hpp"
#include "../ErrorReporting/ErrorContainer.h"
#include "CompilationUnit.h"
#include "PreprocessFile.h"
#include "CompileSourceFile.h"
#include "Compiler.h"
#include "../Utils/StringUtils.h"
#include "../Cache/PPCache.h"
#include "../ErrorReporting/Waiver.h"
#include <cstdlib>
#include <iostream>
#include <regex>
#include <algorithm>

using namespace std;
using namespace SURELOG;

#include "../parser/SV3_1aPpLexer.h"
#include "../parser/SV3_1aPpParser.h"
#include "../parser/SV3_1aPpParserBaseListener.h"
using namespace antlr4;
#include "../Utils/ParseUtils.h"
#include "../Utils/FileUtils.h"
#include "antlr4-runtime.h"
#include "atn/ParserATNSimulator.h"
#include "Parser.h"
std::string PreprocessFile::MacroNotDefined   = "SURELOG_MACRO_NOT_DEFINED";
std::string PreprocessFile::PP__Line__Marking = "SURELOG__LINE__MARKING";
std::string PreprocessFile::PP__File__Marking = "SURELOG__FILE__MARKING";

#include "SV3_1aPpTreeShapeListener.h"

void
PreprocessFile::setDebug (int level)
{
  switch (level)
    {
    case 0:
      m_debugPP = false;
      m_debugPPResult = false;
      m_debugPPTokens = false;
      m_debugPPTree = false;
      m_debugMacro = false;
      break;
    case 1:
      m_debugPP = true;
      m_debugPPResult = false;
      m_debugPPTokens = false;
      m_debugPPTree = false;
      m_debugMacro = false;
      break;
    case 2:
      m_debugPP = true;
      m_debugPPResult = false;
      m_debugPPTokens = true;
      m_debugPPTree = true;
      m_debugMacro = false;
      break;
    case 3:
      m_debugPP = true;
      m_debugPPResult = true;
      m_debugPPTokens = false;
      m_debugPPTree = false;
      m_debugMacro = true;
      break;
    case 4:
      m_debugPP = true;
      m_debugPPResult = true;
      m_debugPPTokens = true;
      m_debugPPTree = true;
      m_debugMacro = true;
      break;
    default:
      break;
    }
}
class PreprocessFile::DescriptiveErrorListener : public ANTLRErrorListener
{
public:
  DescriptiveErrorListener(PreprocessFile* pp, std::string filename) : m_pp(pp), m_fileName(filename) {} 
  
  
  void syntaxError(Recognizer *recognizer, Token *offendingSymbol, size_t line,
                             size_t charPositionInLine, const std::string &msg, std::exception_ptr e); 

  void reportAmbiguity (Parser *recognizer, const dfa::DFA &dfa, size_t startIndex, size_t stopIndex, bool exact,
                        const antlrcpp::BitSet &ambigAlts, atn::ATNConfigSet *configs);

  void reportAttemptingFullContext (Parser *recognizer, const dfa::DFA &dfa, size_t startIndex, size_t stopIndex,
                                    const antlrcpp::BitSet &conflictingAlts, atn::ATNConfigSet *configs);

  void reportContextSensitivity (Parser *recognizer, const dfa::DFA &dfa, size_t startIndex, size_t stopIndex,
                                 size_t prediction, atn::ATNConfigSet *configs);

  PreprocessFile* m_pp;
  std::string m_fileName;
  std::string m_fileContent;
};


void PreprocessFile::DescriptiveErrorListener::syntaxError(Recognizer *recognizer, Token *offendingSymbol, size_t line,
                             size_t charPositionInLine, const std::string &msg, std::exception_ptr e) { 
  SymbolId msgId = m_pp->registerSymbol (msg);

       
  if (m_pp->m_macroInfo)
    {

      std::string lineText = m_pp->getMacroBody ();
      for (unsigned int i = 0; i < charPositionInLine; i++)
        lineText += " ";
      lineText += "^-- " + m_fileName + ":" + std::to_string (line) + " col:" + std::to_string (charPositionInLine);
      msgId = m_pp->registerSymbol (msg + "," + lineText);
      Location loc (m_pp->getMacroInfo()->m_file, m_pp->getMacroInfo()->m_line + line -1, charPositionInLine, msgId);
      Location extraLoc (m_pp->getIncluderFileId (m_pp->getIncluderLine ()), m_pp->getIncluderLine (), 0, 0);
      Error err (ErrorDefinition::PP_MACRO_SYNTAX_ERROR, loc, extraLoc);
      m_pp->addError (err);
    }
  else
    {

      if (m_fileContent == "")
        {
          m_fileContent = FileUtils::getFileContent (m_fileName);
        }

      std::string lineText;
      if (m_fileContent != "")
        {
          lineText = StringUtils::getLineInString (m_fileContent, line);
          if (lineText != "")
            {
              if (!strstr (lineText.c_str (), "\n"))
                {
                  lineText += "\n";
                }
              for (unsigned int i = 0; i < charPositionInLine; i++)
                lineText += " ";
              lineText += "^-- " + m_fileName + ":" + std::to_string (line) + " col:" + std::to_string (charPositionInLine);
            }
        } 
      
      Location loc2 (0, 0, 0, m_pp->registerSymbol (lineText));
      
      Location loc (m_pp->getFileId (line), line, charPositionInLine, msgId);
      Error err (ErrorDefinition::PP_SYNTAX_ERROR, loc, loc2);
      m_pp->addError (err);
    }
}

void
PreprocessFile::DescriptiveErrorListener::reportAmbiguity (Parser *recognizer, const dfa::DFA &dfa, size_t startIndex, size_t stopIndex, bool exact,
                                           const antlrcpp::BitSet &ambigAlts, atn::ATNConfigSet *configs) { }

void
PreprocessFile::DescriptiveErrorListener::reportAttemptingFullContext (Parser *recognizer, const dfa::DFA &dfa, size_t startIndex, size_t stopIndex,
                                                       const antlrcpp::BitSet &conflictingAlts, atn::ATNConfigSet *configs) { }

void
PreprocessFile::DescriptiveErrorListener::reportContextSensitivity (Parser *recognizer, const dfa::DFA &dfa, size_t startIndex, size_t stopIndex,
                                                    size_t prediction, atn::ATNConfigSet *configs) { }


PreprocessFile::PreprocessFile(SymbolId fileId, CompileSourceFile* csf, SpecialInstructions& instructions, CompilationUnit* comp_unit, Library* library) : 
    m_fileId(fileId), m_library(library), m_result(""), m_macroBody(""), m_includer(NULL), m_includerLine(0), m_compileSourceFile(csf), m_lineCount(0), m_listener(NULL), 
        m_instructions(instructions), m_antlrParserHandler(NULL), m_macroInfo(NULL), m_compilationUnit(comp_unit), m_pauseAppend(false),
        m_usingCachedVersion(false), m_embeddedMacroCallLine(0), m_embeddedMacroCallFile(0) {
  setDebug(m_compileSourceFile->m_commandLineParser->getDebugLevel ());
  IncludeFileInfo info (1, m_fileId, 1,1);
  info.m_indexClosing = 0;
  info.m_indexOpening = 0;
  getIncludeFileInfo ().push_back (info);
}

PreprocessFile::PreprocessFile(SymbolId fileId, PreprocessFile* includedIn, unsigned int includerLine, CompileSourceFile* csf, 
                               SpecialInstructions& instructions, CompilationUnit* comp_unit, Library* library,
                               std::string macroBody, MacroInfo* macroInfo, unsigned int embeddedMacroCallLine, SymbolId embeddedMacroCallFile): 
    m_fileId(fileId), m_library(library), m_result(""), m_macroBody(macroBody) , m_compileSourceFile(csf), m_lineCount(0), m_listener(NULL),
    m_instructions(instructions), m_antlrParserHandler(NULL), m_macroInfo(macroInfo), m_compilationUnit(comp_unit), m_pauseAppend(false),
    m_usingCachedVersion(false), m_embeddedMacroCallLine(embeddedMacroCallLine), m_embeddedMacroCallFile(embeddedMacroCallFile) {
  setDebug(m_compileSourceFile->m_commandLineParser->getDebugLevel ());
  m_includer = includedIn;
  m_includerLine = includerLine;
  if (includedIn)
    {
      includedIn->m_includes.push_back (this);
    }
}

void
PreprocessFile::addError (Error& error)
{
  if (!m_instructions.m_mute)
    getCompileSourceFile()->getErrorContainer ()->addError (error);

}

 const std::string PreprocessFile::getSymbol(SymbolId id) {
   return getCompileSourceFile()->getSymbolTable()->getSymbol(id);
 }

const std::string PreprocessFile::getFileName(unsigned int line) {
  return getSymbol(getFileId(line));
}

SymbolId PreprocessFile::getMacroSignature()
{
  std::string macroSignature = getSymbol(m_fileId);
  if (m_macroInfo)
    {
      macroSignature += "|" + getSymbol (m_macroInfo->m_file);
      macroSignature += "|" + std::to_string (m_macroInfo->m_line);
    }
  macroSignature += "|" + m_macroBody;
  SymbolId sigId = registerSymbol (macroSignature);
  return sigId;
}


PreprocessFile::PreprocessFile (const PreprocessFile& orig) { }

PreprocessFile::~PreprocessFile () { 
  if (m_listener)
    delete m_listener;
}

PreprocessFile::AntlrParserHandler::~AntlrParserHandler ()
{
  delete m_errorListener;
  //delete m_pptree;  // INVALID MEMORY READ can be seen in AdvancedDebug
  delete m_ppparser;
  delete m_pptokens;
  delete m_pplexer;
  delete m_inputStream;
}

bool
PreprocessFile::preprocess ()
{
  PPCache cache (this);
  if (cache.restore ())
    {
      m_usingCachedVersion = true;
      getCompilationUnit()->setCurrentTimeInfo(getFileId(0));
      return true;
    }
  
  m_result = "";
  std::string fileName = getSymbol (m_fileId);
 
  m_antlrParserHandler = getCompileSourceFile()->getAntlrPpHandlerForId ((m_macroBody == "") ? m_fileId : getMacroSignature());
  
  if (m_antlrParserHandler == NULL)
    {
      m_antlrParserHandler = new AntlrParserHandler ();
      if (m_macroBody != "")
        {
          if (m_debugPP)
            {
              std::cout << "PP PREPROCESS MACRO: " << m_macroBody << endl;
            }
          m_antlrParserHandler->m_inputStream = new ANTLRInputStream (m_macroBody);
        }
      else
        {

          if (m_debugPP)
            std::cout << "PP PREPROCESS FILE: " << fileName << endl;
          std::ifstream stream;
          stream.open (fileName);
          if (!stream.good ())
            {
              if (m_includer == NULL)
                {
                  Location loc (m_fileId);
                  Error err (ErrorDefinition::PP_CANNOT_OPEN_FILE, loc);
                  addError (err);
                }
              else
                {
                  Location includeFile (m_includer->m_fileId, m_includerLine, 0, m_fileId);
                  Error err (ErrorDefinition::PP_CANNOT_OPEN_INCLUDE_FILE, includeFile);
                  addError (err);
                }
              return false;
            }
          try {
              m_antlrParserHandler->m_inputStream = new ANTLRInputStream (stream);
              stream.close();
          } catch (...) {
              Location loc(0);
              if (m_includer == NULL)
                {
                  Location file (m_fileId);
                  loc = file;
                }
              else
                {
                  Location includeFile (m_includer->m_fileId, m_includerLine, 0, m_fileId);
                  loc = includeFile;
                }
              Error err (ErrorDefinition::PP_CANNOT_READ_FILE_CONTENT, loc);
              addError (err);  
              return false;
          }

        }
      m_antlrParserHandler->m_errorListener = new PreprocessFile::DescriptiveErrorListener(this, (m_macroBody == "") ? fileName : "in macro " + fileName);
      m_antlrParserHandler->m_pplexer = new SV3_1aPpLexer (m_antlrParserHandler->m_inputStream);
      m_antlrParserHandler->m_pplexer->removeErrorListeners();
      m_antlrParserHandler->m_pplexer->addErrorListener(m_antlrParserHandler->m_errorListener);
      m_antlrParserHandler->m_pptokens = new CommonTokenStream (m_antlrParserHandler->m_pplexer);
      m_antlrParserHandler->m_pptokens->fill ();

      if (m_debugPPTokens)
        {
          std::cout << "PP TOKENS: " << std::endl;
          for (auto token : m_antlrParserHandler->m_pptokens->getTokens ())
            {
              std::cout << token->toString () << std::endl;
            }
        }

      m_antlrParserHandler->m_ppparser = new SV3_1aPpParser (m_antlrParserHandler->m_pptokens);
      m_antlrParserHandler->m_ppparser->getInterpreter<atn::ParserATNSimulator>()->setPredictionMode (atn::PredictionMode::SLL);
      m_antlrParserHandler->m_ppparser->removeErrorListeners(); 
      m_antlrParserHandler->m_ppparser->setErrorHandler(std::make_shared<BailErrorStrategy>());
      try
        {
          m_antlrParserHandler->m_pptree = m_antlrParserHandler->m_ppparser->source_text ();
        }
      catch (ParseCancellationException& pex)
        {
          m_antlrParserHandler->m_pptokens->reset();
          m_antlrParserHandler->m_ppparser->reset();
          m_antlrParserHandler->m_ppparser->addErrorListener (m_antlrParserHandler->m_errorListener);
          m_antlrParserHandler->m_ppparser->setErrorHandler (std::make_shared<DefaultErrorStrategy>());
          m_antlrParserHandler->m_ppparser->getInterpreter<atn::ParserATNSimulator>()->setPredictionMode (atn::PredictionMode::LL);
          m_antlrParserHandler->m_pptree = m_antlrParserHandler->m_ppparser->source_text ();        
        }

      
      if (m_debugPPTree)
        std::cout << "PP TREE: " << m_antlrParserHandler->m_pptree->toStringTree (m_antlrParserHandler->m_ppparser) << std::endl << std::endl;

      getCompileSourceFile ()->registerAntlrPpHandlerForId ((m_macroBody == "") ? m_fileId : getMacroSignature(), m_antlrParserHandler);
    }
  if (m_listener == NULL)
    m_listener = new SV3_1aPpTreeShapeListener (this,m_instructions);
  tree::ParseTreeWalker::DEFAULT.walk (m_listener, m_antlrParserHandler->m_pptree);
  
  return true;
}

unsigned int  PreprocessFile::getSumLineCount() {
  unsigned int total = m_lineCount;
  if (m_includer)
    total += m_includer->getSumLineCount();
  return total;
}

static unsigned int
LinesCount (const std::string& s)
{
  return std::count (s.begin (), s.end (), '\n');
}

void PreprocessFile::append(const std::string& s) {
  if (!m_pauseAppend)
    {
      m_lineCount += LinesCount(s);
      m_result += s;
    }
}

void PreprocessFile::recordMacro(const std::string name, unsigned int line, unsigned short int column, const std::string arguments, const std::vector<std::string> tokens) 
{
  // *** Argument processing
  std::string arguments_short = arguments;
  // Remove (
  size_t p = arguments_short.find('(');
  if (p != string::npos) 
    {
        arguments_short.erase(p,1);
    }
  // Remove )
  p = arguments_short.find(')');
  if (p != string::npos) 
    {
        arguments_short.erase(p,1);
    }
  // Tokenize args
  std::vector<std::string> args;  
  StringUtils::tokenize(arguments_short, ",", args);
  
  if (m_debugMacro)
    {
      std::string body;
      for (auto token : tokens)
        {
          body += token;
        }
      std::cout << "PP RECORDING MACRO: " << name  << ": | " << body  << " | " << endl;
    }
  
  //std::cout << "PP RECORDING MACRO: " << name  << ", FILE: " <<  getSymbol(getFileId(line)) << "" << endl;
  
  MacroInfo* macroInfo = new MacroInfo(name, arguments.size() ? MacroInfo::WITH_ARGS : MacroInfo::NO_ARGS, getFileId(line), line, column, args, tokens);
  m_macros.insert(std::make_pair(name, macroInfo));
  m_compilationUnit->registerMacroInfo (name, macroInfo);
  checkMacroArguments_(name, line, column, args, tokens);
}


std::string PreprocessFile::reportIncludeInfo() {
  std::string report;
  for (auto info : m_includeFileInfo)
    {
      std::string type = (info.m_type == 1) ? "in" : "out";
      report += std::to_string(info.m_originalLine) + " " + getSymbol(info.m_sectionFile) + " " + std::to_string(info.m_sectionStartLine) + " " + type + "\n";
    }
  
  return report;
}

void PreprocessFile::recordMacro(const std::string name, unsigned int line, unsigned short int column, const std::vector<std::string> arguments, const std::vector<std::string> tokens) 
{
  MacroInfo* macroInfo = new  MacroInfo(name, arguments.size() ? MacroInfo::WITH_ARGS : MacroInfo::NO_ARGS, getFileId(line), line, column, arguments, tokens);
  m_macros.insert(std::make_pair(name, macroInfo));
  m_compilationUnit->registerMacroInfo (name, macroInfo);
}

void PreprocessFile::checkMacroArguments_(const std::string& name, unsigned int line, unsigned short column, 
                                          const std::vector<std::string>& arguments, const std::vector<std::string>& tokens) {
  std::set<std::string> argSet;
  std::set<std::string> tokenSet;
  for (auto s : arguments) { argSet.insert(StringUtils::trim(StringUtils::rtrimEqual(StringUtils::trim(s)))); }
  for (auto s : tokens) { tokenSet.insert(StringUtils::trim(s)); }
  for (auto s : argSet)
    {
      if (tokenSet.find (s) == tokenSet.end () && tokenSet.find ("``" + s + "``") == tokenSet.end ()
          && tokenSet.find (s + "``") == tokenSet.end ())
        {
          Location loc (m_fileId, line, column, registerSymbol (s));
          Error err (ErrorDefinition::PP_MACRO_UNUSED_ARGUMENT, loc);
          addError (err);
        }
    }
  for (unsigned int i = 0; i < tokens.size(); i++)
    {
      std::string s1 = tokens[i];
      std::string s2 = tokens[i];
      bool check = false;
      if ((s1.find ("``") != std::string::npos) && (s1 != "``")) // ``a``
        {
          s1 = std::regex_replace (s1, std::regex ("``"), "");
          s2 = s1;
          check = true;
        }
      else if (s1 == "``")
        {
          if (i > 0)
            s1 = tokens[i - 1];
          s1 = StringUtils::trim (s1);
          s2 = tokens[i + 1];
          s2 = StringUtils::trim (s2);
          check = true;
        }
      if (check)
        {
          if ((argSet.find (s1) == argSet.end ()) && (argSet.find (s2) == argSet.end ()))
            {
              for (auto s :{s1, s2})
                {
                  if (argSet.find (s) == argSet.end ())
                    {
                      if (s.find ("`") != std::string::npos)
                        continue;
                      if (s.find ("//") != std::string::npos)
                        continue;
                      if (!std::isalpha (s[0]))
                        continue;
                      Location loc (m_fileId, line, column, registerSymbol (s));
                      Error err (ErrorDefinition::PP_MACRO_UNDEFINED_ARGUMENT, loc);
                      addError (err);
                    }
                }
            }
        }
    } 
}


SymbolId PreprocessFile::getIncluderFileId(unsigned int line) {
  PreprocessFile* tmp = this;
  while (tmp->m_includer != NULL) {
      tmp = tmp->m_includer;
  }
  return tmp->getFileId(line);
}


PreprocessFile* PreprocessFile::getSourceFile() {
  PreprocessFile* tmp = this;
  while (tmp->m_includer != NULL) {
      tmp = tmp->m_includer;
  }
  return tmp;
}

void PreprocessFile::forgetPreprocessor_(PreprocessFile* inc, PreprocessFile* pp)
{
  for (std::vector<PreprocessFile*>::iterator itr = inc->m_includes.begin (); itr != inc->m_includes.end (); itr++)
    {
      if ((*itr) == pp)
        {
          inc->m_includes.erase (itr);
          break;
        }
    }
}

SymbolId PreprocessFile::registerSymbol(const std::string symbol) {
  return getCompileSourceFile()->getSymbolTable()->registerSymbol(symbol);
}

SymbolId PreprocessFile::getId(const std::string symbol) {
  return getCompileSourceFile()->getSymbolTable()->getId(symbol);
}

std::string PreprocessFile::evaluateMacroInstance(const std::string macro_instance, PreprocessFile* callingFile, 
                                                  unsigned int callingLine, 
                                                  SpecialInstructions::CheckLoopInstr checkMacroLoop, 
                                                  SpecialInstructions::AsIsUndefinedMacroInstr asisUndefMacro)
{
  std::string result;
  //SymbolId macroArgs = registerSymbol (macro_instance);
  SpecialInstructions instructions (SpecialInstructions::Mute, SpecialInstructions::Mark, SpecialInstructions::Filter, checkMacroLoop, asisUndefMacro);
  PreprocessFile* pp = new PreprocessFile (0, /*macroArgs,*/ NULL, 0 /*m_includer ? m_includer : callingFile, callingLine*/, m_compileSourceFile,
                                           instructions, m_includer ? m_includer->m_compilationUnit : callingFile->m_compilationUnit, callingFile->m_library, macro_instance);
  if (!pp->preprocess ())
    {
      result = MacroNotDefined;
    }
  else
    {
      result = pp->getPreProcessedFileContent ();
    }
  forgetPreprocessor_ (m_includer ? m_includer : callingFile, pp);
  delete pp;
  return result;
}


std::pair<bool, std::string> PreprocessFile::evaluateMacro_ (const std::string name, std::vector<std::string>& actual_args, PreprocessFile* callingFile, 
                                                             unsigned int callingLine,
                                                             LoopCheck& loopChecker, 
                                                             MacroInfo* macroInfo, SpecialInstructions& instructions,
                                                             unsigned int embeddedMacroCallLine, SymbolId embeddedMacroCallFile)
{
  std::string result;
  bool found = false; 
  std::vector<std::string>& formal_args = macroInfo->m_arguments;
  // Don't modify the actual tokens of the macro, make a copy...
  std::vector<std::string> body_tokens = macroInfo->m_tokens;

  if (instructions.m_check_macro_loop)
    {
      bool loop = loopChecker.addEdge (callingFile->m_fileId, getId (name));
      if (loop)
        {
          std::vector<SymbolId> loop = loopChecker.reportLoop ();
          for (auto id : loop)
            {
              MacroInfo* macroInfo2 = m_compilationUnit->getMacroInfo(getSymbol(id));
              if (macroInfo2)
                {
                  Location loc (macroInfo2->m_file, macroInfo2->m_line, 0, id);
                  Location exloc (macroInfo->m_file, macroInfo->m_line, 0, getId (name));
                  Error err (ErrorDefinition::PP_RECURSIVE_MACRO_DEFINITION, loc, exloc);
                  addError (err);
                  return std::make_pair (false, getCompileSourceFile ()->getCompiler ()->getSymbolTable ()->getBadSymbol ());
                }
            }
        }
    }
  
  StringUtils::replaceInTokenVector (body_tokens, "`\"", "\"");
  StringUtils::replaceInTokenVector (body_tokens, "`\\`\"", "\\\"");
  
  // argument substitution
  
  for (unsigned int i = 0; i < actual_args.size (); i++)
    {
      if (actual_args[i].find ('`') != std::string::npos)
        {
          actual_args[i] = evaluateMacroInstance(actual_args[i], callingFile, callingLine, 
                                                 SpecialInstructions::CheckLoop, 
                                                 SpecialInstructions::AsIsUndefinedMacroInstr::ComplainUndefinedMacro);
        }
    }
  
  if ((actual_args.size() > formal_args.size() && (!m_instructions.m_mute))) 
    {
      if (formal_args.size() == 0 && (StringUtils::getFirstNonEmptyToken(body_tokens) == "("))
        {
          Location loc (macroInfo->m_file, macroInfo->m_line, macroInfo->m_column + name.size() + 1 , getId (name));
          Error err (ErrorDefinition::PP_MACRO_HAS_SPACE_BEFORE_ARGS, loc);
          addError (err);
        }
      else 
        {
          if (!Waiver::macroArgCheck (name))
            {
              Location loc (callingFile->getFileId (callingLine), callingFile->getLineNb (callingLine), 0, getId (name));
              Location arg (0, 0, 0, registerSymbol (std::to_string (actual_args.size ())));
              Location def (macroInfo->m_file, macroInfo->m_line, 0, registerSymbol (std::to_string (formal_args.size ())));
              std::vector<Location> locs = {arg, def};
              Error err (ErrorDefinition::PP_TOO_MANY_ARGS_MACRO, loc, &locs);
              addError (err);
            }
        }
    }
  
  for (unsigned int i = 0; i < formal_args.size (); i++)
    {
      std::vector<std::string> formal_arg_default;
      StringUtils::tokenize (formal_args[i], "=", formal_arg_default);
      std::string formal = std::regex_replace (formal_arg_default[0], std::regex ("[ \t]*"), "");
      bool empty_actual = true;
      if (i < actual_args.size ())
        {
          for (unsigned int ii = 0; ii < actual_args[i].size (); ii++)
            { 
              if (actual_args[i][ii] != ' ')
                {
                  empty_actual = false;
                  break;
                }
            }
        }
      if (!empty_actual)
        {
          if (actual_args[i] == SymbolTable::getEmptyMacroMarker ())
             {
               actual_args[i] = "";
             }
          
          StringUtils::replaceInTokenVector (body_tokens, { "``",  formal , "``" }, actual_args[i]); 
          StringUtils::replaceInTokenVector (body_tokens, "``" + formal + "``", actual_args[i]); 
          StringUtils::replaceInTokenVector (body_tokens, {formal, "``"}, actual_args[i]);
          StringUtils::replaceInTokenVector (body_tokens, {"``", formal}, actual_args[i]);
          StringUtils::replaceInTokenVector (body_tokens, {formal, " " , "``"}, actual_args[i]);
          StringUtils::replaceInTokenVector (body_tokens, formal + "``", actual_args[i]);
          StringUtils::replaceInTokenVector (body_tokens, formal, actual_args[i]);
        }
      else
        {
          if (formal_arg_default.size () == 2)
            {
              std::string default_val = std::regex_replace (formal_arg_default[1], std::regex ("[ \t]*"), "");
              StringUtils::replaceInTokenVector (body_tokens, {"``", formal, "``" }, default_val);
              StringUtils::replaceInTokenVector (body_tokens, "``" + formal + "``", default_val);
              StringUtils::replaceInTokenVector (body_tokens, {formal, "``"}, default_val);
              StringUtils::replaceInTokenVector (body_tokens, {"``", formal}, default_val);
              StringUtils::replaceInTokenVector (body_tokens, {formal, " ", "``"}, default_val);
              StringUtils::replaceInTokenVector (body_tokens, formal + "``", default_val);
              StringUtils::replaceInTokenVector (body_tokens, formal, default_val);
            }
          else 
            {
              StringUtils::replaceInTokenVector (body_tokens,{"``", formal, "``"}, "");
              StringUtils::replaceInTokenVector (body_tokens, "``" + formal + "``", "");
              StringUtils::replaceInTokenVector (body_tokens,{formal, "``"}, "");
              StringUtils::replaceInTokenVector (body_tokens,{"``", formal}, "");
              StringUtils::replaceInTokenVector (body_tokens,{formal, " ", "``"}, "");
              StringUtils::replaceInTokenVector (body_tokens, formal + "``", "");
              StringUtils::replaceInTokenVector (body_tokens, formal, "");
              
              if ((int)i > (int)(((int)actual_args.size()) -1))
                {
                  if (!instructions.m_mute)
                    {
                      Location loc (callingFile->getFileId (callingLine), callingFile->getLineNb(callingLine), 0, getId (name));
                      SymbolId id = registerSymbol (std::to_string (i + 1) + " (" + formal + ")");
                      Location arg (0, 0, 0, id);
                      Location def (macroInfo->m_file, macroInfo->m_line, 0, id);
                      std::vector<Location> locs = {arg, def};
                      Error err (ErrorDefinition::PP_MACRO_NO_DEFAULT_VALUE, loc, &locs);
                      addError (err);
                    }
                }
            }
        } 
    }
  
  std::string body;
  for (auto token : body_tokens)
    {
      body += token;
    }

  // *** Body processing
  std::string body_short = body;
  // Replace \\n by \n

  for (string::iterator itr = body_short.end (); itr != body_short.begin (); itr--)
    {
      if ((*itr) == '\n')
        {
          if ((itr != body_short.begin ()) && (*(itr - 1) == '\\'))
            {
              body_short.erase (itr - 1);
            }
        }
    }

  // Truncate trailing carriage returns (up to 2)

  for (int i = 0; i < 2; i++)
    {
      if (body_short.size ())
        {
          if (body_short.at (body_short.size () - 1) == '\n')
            {
              body_short.erase (body_short.size () - 1);
            }
          else
            {
              break;
            }
        }
    }

  // If it is a Multiline macro, insert a \n at the end

  if (body_short.find ('\n') != string::npos)
    {
      body_short.push_back ('\n');
    }

  if (body_short.find ('`') != std::string::npos)
    {
      // Recursively resolve macro instantiation within the macro
      if (m_debugMacro)
        {
          const std::string fileName = getSymbol (m_fileId);
          std::cout << "PP BODY EXPANSION FOR " << name << " in : " << fileName << std::endl;
          for (auto arg : actual_args)
            {
              std::cout << "PP ARG: " << arg << "\n";
            }
        }
      SymbolId macroId = registerSymbol (name);
      SpecialInstructions instructions (m_instructions.m_mute, 
                                        SpecialInstructions::DontMark,
                                        SpecialInstructions::Filter, 
                                        m_instructions.m_check_macro_loop,
                                        m_instructions.m_as_is_undefined_macro);
      PreprocessFile* pp = new PreprocessFile (macroId, callingFile ? callingFile : m_includer 
                                               , callingLine, m_compileSourceFile, 
                                               instructions, callingFile ? callingFile->m_compilationUnit : m_includer->m_compilationUnit,
                                               callingFile ? callingFile->m_library : m_includer->m_library , 
                                               body_short, macroInfo,
                                               embeddedMacroCallLine, embeddedMacroCallFile);
      getCompileSourceFile()->registerPP(pp);
      if (!pp->preprocess ())
        {
          result = MacroNotDefined;
        }
      else
        {      
          std::string pp_result = pp->getPreProcessedFileContent ();

          if (callingLine && callingFile && !callingFile->isMacroBody ())
            {
              pp_result = std::regex_replace (pp_result, std::regex(PP__File__Marking), "\"" + FileUtils::getFullPath(callingFile->getFileName(callingLine)) + "\"" );
              pp_result = std::regex_replace (pp_result, std::regex(PP__Line__Marking), std::to_string (callingLine));
            }          
          result = pp_result;
          found = true;
        }
    }
  else
    {
      result = body_short;
      found = true;
    }
  return std::make_pair(found, result);
}


MacroInfo* PreprocessFile::getMacro(const std::string name) {
  registerSymbol(name);
  return m_compilationUnit->getMacroInfo(name);
}

bool PreprocessFile::deleteMacro (const std::string name, std::set<PreprocessFile*>& visited) {
  /*SymbolId macroId = */ registerSymbol(name);
  if (m_debugMacro)
    std::cout << "PP CALL TO deleteMacro for " << name << std::endl; 
  bool found = false;
  // Try CommandLine overrides
  //const std::map<SymbolId,std::string>& defines = m_compileSourceFile->m_commandLineParser->getDefineList();
  //std::map<SymbolId,std::string>::const_iterator itMap = defines.find(macroId);
  // if (itMap != defines.end())
  //  {
  //    result = (*itMap).second;
  //    found = true;
  //  }

  // Try local file scope
  if (found == false)
    {
      MacroStorage::iterator itr = m_macros.find (name);
      if (itr != m_macros.end ())
        {
          m_macros.erase(itr);
          m_compilationUnit->deleteMacro (name);
          found = true;
        }
    }
  // Try in included files
  if (found == false)
    {
      for (std::vector<PreprocessFile*>::iterator iitr = m_includes.begin (); iitr != m_includes.end (); iitr++)
        {
          PreprocessFile* pFile = *iitr;
          if (visited.find (pFile) == visited.end ())
            {
              visited.insert (pFile);
              bool tmp = pFile->deleteMacro (name, visited);
              if (tmp == true)
                {
                  found = true;
                  break;
                }
            }
        }
    }
  // Try in file that included this file
  if (found == false)
    {
      if (m_includer)
        {
          if (visited.find (m_includer) == visited.end ())
            {
              visited.insert (m_includer);
              bool tmp = m_includer->deleteMacro (name, visited);
              if (tmp == true)
                {
                  found = true;
                }
            }
        }
    }
  return found;
}

void PreprocessFile::undefineAllMacros(std::set<PreprocessFile*>& visited) {

  if (m_debugMacro)
    std::cout << "PP CALL TO undefineAllMacros" << std::endl;
  m_macros.clear ();
  m_compilationUnit->deleteAllMacros();

  for (std::vector<PreprocessFile*>::iterator iitr = m_includes.begin (); iitr != m_includes.end (); iitr++)
    {
      PreprocessFile* pFile = *iitr;
      if (visited.find (pFile) == visited.end ())
        {
          visited.insert (pFile);
          pFile->undefineAllMacros (visited);
        }
    }

  if (m_includer)
    {
      if (visited.find (m_includer) == visited.end ())
        {
          visited.insert (m_includer);
          m_includer->undefineAllMacros(visited);
        }
    }
}

std::string
PreprocessFile::getMacro (const std::string name, std::vector<std::string>& arguments, PreprocessFile* callingFile, 
                          unsigned int callingLine, LoopCheck& loopChecker, SpecialInstructions& instructions,
                          unsigned int embeddedMacroCallLine, SymbolId embeddedMacroCallFile)
{
  SymbolId macroId = registerSymbol(name);
  if (m_debugMacro) 
    {
      std::cout << "PP CALL TO getMacro for " << name << "\n";
      for (auto arg : arguments)
        {
          std::cout << "PP ARG: " << arg << "\n";
        }
      instructions.print();
    }
  std::string result;
  bool found = false;
  // Try CommandLine overrides
  const std::map<SymbolId,std::string>& defines = m_compileSourceFile->m_commandLineParser->getDefineList();
  std::map<SymbolId,std::string>::const_iterator itMap = defines.find(macroId);
  if (itMap != defines.end())
    {
      result = (*itMap).second;
      found = true;
    }
 
  // Try local file scope
  if (found == false)
    {
      MacroInfo* info = m_compilationUnit->getMacroInfo(name);
      if (info)
        {
          std::pair<bool, std::string> evalResult = evaluateMacro_(name, arguments, callingFile, callingLine, loopChecker, info, instructions, 
                                                                   embeddedMacroCallLine, embeddedMacroCallFile);
          found = evalResult.first;
          result = evalResult.second; 
          result = std::regex_replace (result, std::regex ("``"), "");
        }
    }
  if (found == false)
    {
      if (instructions.m_as_is_undefined_macro == SpecialInstructions::AsIsUndefinedMacro)
        {
          return "`" + name;
        }
      else 
        {
          return MacroNotDefined;
        }
    }
  else
    {
      return result;
    }
   
}

SymbolId
PreprocessFile::getFileId (unsigned int line)
{
  const unsigned int size = m_lineTranslationVec.size ();
  if (isMacroBody() && m_macroInfo)
    {
      return m_macroInfo->m_file;
    }
  else 
    {
      if (size)
        {
          if (size == 1)
            {
              if (line >= m_lineTranslationVec[0].m_originalLine)
                {
                  return (m_lineTranslationVec[0].m_pretendFileId);
                }
            }
          else 
            {
              for (unsigned int i = size - 1; i >= 0; i--)
                {
                  if (line >= m_lineTranslationVec[i].m_originalLine)
                    {
                      return (m_lineTranslationVec[i].m_pretendFileId);
                    }
                }
            }
          return m_fileId;
        }
      else
        {
          return m_fileId;
        }
    }
}

unsigned int
PreprocessFile::getLineNb (unsigned int line)
{
   if (isMacroBody() && m_macroInfo)
    {
      return (m_macroInfo->m_line + line -1);
    }
  else 
    {
      if (m_lineTranslationVec.size ())
        {
          for (unsigned int i = m_lineTranslationVec.size () - 1; i >= 0; i--)
            {
              if (line >= m_lineTranslationVec[i].m_originalLine)
                {
                  return (m_lineTranslationVec[i].m_pretendLine + (line - m_lineTranslationVec[i].m_originalLine));
                }
            }
          return line;
        }
      else
        {
          return line;
        }
    }
}


std::string PreprocessFile::getPreProcessedFileContent()
{
  // If File is empty (Only CR) return an empty string
  bool nonEmpty = false;
  unsigned int pp_result_size = m_result.size ();
  for (unsigned int i = 0; i < pp_result_size; i++)
    {
      if ((m_result[i] != '\n') && (m_result[i] != ' '))
        {
          nonEmpty = true;
          break;
        }
    }
  if (!nonEmpty)
     m_result = "";
  if (m_debugPPResult)
    {
      const std::string fileName = getSymbol(m_fileId);
      std::string objName =  (m_macroBody != "") ? "macro "  + m_macroBody : "file " + fileName;
      std::cout << "PP RESULT for " << objName
              << " : \nvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n"
              << m_result 
              <<    "\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" 
              << std::endl;
    }
  return m_result;
}

PreprocessFile::IfElseStack& PreprocessFile::getStack() {
  PreprocessFile* tmp = this;
  while (tmp->m_includer != NULL) {
      tmp = tmp->m_includer;
  }
  //std::cout << "STACK FOR: " << tmp->m_fileName << std::endl;
  return tmp->m_ifStack;
}

void
PreprocessFile::collectIncludedFiles (std::set<PreprocessFile*>& included)
{
  for (std::vector<PreprocessFile*>::iterator itr = m_includes.begin (); itr != m_includes.end (); itr++)
    {
      if (!(*itr)->isMacroBody ())
        {
          included.insert (*itr);
        }
      (*itr)->collectIncludedFiles(included);
      
    }
}

void PreprocessFile::saveCache() {
   if (m_macroBody == "")
    {
      if (!m_usingCachedVersion) {
          PPCache cache(this);
          cache.save();
        }
    }
    for (std::vector<PreprocessFile*>::iterator itr = m_includes.begin (); itr != m_includes.end (); itr++) 
      {
        (*itr)->saveCache();
      }
}




