text:
  #include <iostream>                  // for std::cout
  #include <utility>                   // for std::pair
  #include <algorithm>                 // for std::for_each
  #include <boost/graph/graph_traits.hpp>
  #include <boost/graph/adjacency_list.hpp>
  #include <boost/graph/dijkstra_shortest_paths.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/map.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <sstream>
#include <string>
#include <boost/iostreams/device/file.hpp>
#include <boost/iostreams/stream.hpp>
#include <istream>
#include <regex>
#include "slice_optimizer.h"
#include <boost/algorithm/string.hpp>
#include <boost/numeric/ublas/vector.hpp>

using namespace boost;

//#define DEBUG_PRINT
//#define EDGES_PRINT
#define VAL_EQV
#define TRANS_IMME

//from taint_full_interface.c.
//the regToNumSize table in slice_optimizer.h is similar and returns -1 for the MostSigByte, or high half, such as AH and returns 1 for the leastSigByte, or low half such as AL.
static inline const char* regName (int reg_num, int reg_size)
  {
      switch (reg_num) {
      case 3:
    switch (reg_size) {
    case 4: return "edi";
    case 2: return "di";
    }
    break;
      case 4:
    switch (reg_size) {
    case 4: return "esi";
    case 2: return "si";
    }
    break;
      case 5:
    switch (reg_size) {
    case 4: return "ebp";
    case 2: return "bp";
    }
    break;
      case 6:
    switch (reg_size) {
    case 4: return "esp";
    case 2: return "sp";
    }
    break;
      case 7:
    switch (reg_size) {
    case 4: return "ebx";
    case 2: return "bx";
    case 1: return "bl";
    case -1: return "bh";
    }
    break;
      case 8:
    switch (reg_size) {
    case 4: return "edx";
    case 2: return "dx";
    case 1: return "dl";
    case -1: return "dh";
    }
    break;
      case 9:
    switch (reg_size) {
    case 4: return "ecx";
    case 2: return "cx";
    case 1: return "cl";
    case -1: return "ch";
    }
    break;
      case 10:
    switch (reg_size) {
    case 4: return "eax";
    case 2: return "ax";
    case 1: return "al";
    case -1: return "ah";
    }
    break;
      case 17:
    switch (reg_size) {
    case 4: return "eflag";
    }
    break;
      case 20:
    switch (reg_size) {
    case 2: return "ds";
    }
    break;
      case 21:
    switch (reg_size) {
    case 2: return "es";
    }
    break;
      case 54:
    switch (reg_size) {
    case 16: return "xmm0";
    }
    break;
      case 55:
    switch (reg_size) {
    case 16: return "xmm1";
    }
    break;
      case 56:
    switch (reg_size) {
    case 16: return "xmm2";
    }
    break;
      case 57:
    switch (reg_size) {
    case 16: return "xmm3";
    }
    break;
      case 58:
    switch (reg_size) {
    case 16: return "xmm4";
    }
    break;
      case 59:
    switch (reg_size) {
    case 16: return "xmm5";
    }
    break;
      case 60:
    switch (reg_size) {
    case 16: return "xmm6";
    }
    break;
      case 61:
    switch (reg_size) {
    case 16: return "xmm7";
    }
    break;
      }
      fprintf (stderr, "regName: unrecognized reg %d size %d\n", reg_num, reg_size);
      assert (0);
      return NULL;
  }

std::pair<int, int> checkForRegs(std::string instOperand){
  std::pair<int, int> regNumSize (NULL,NULL);
  regNumSize.first =(regToNumSize[instOperand]).first;
  regNumSize.second = (regToNumSize[instOperand]).second;

  #ifdef DEBUG_PRINT
    std::cout<< instOperand << "\n";
    std::cout<< regNumSize.first << "\n";
    std::cout<< regNumSize.second << "\n";
  #endif

  return regNumSize;

}

static inline void clear_reg_internal (int reg, int size)
  {
      int i = 0;

      Node* p_Zero = 0;

      for (i = 0; i < size; i++) {
          shadow_reg_table[reg * REG_SIZE + i] = p_Zero;
      }
  }

 static inline void set_reg_internal (int reg, int size, Node* author)
  {
      int i = 0;
      int offset = 0;

      if (size == -1){
        size = 1;
        offset = 1;
      }

      for (i = 0; i < size; i++) {
          shadow_reg_table[((reg * REG_SIZE) + i)+offset] = author;
          #ifdef DEBUG_PRINT
            std::cout<< "Setting shadow_reg_table at " << (reg * REG_SIZE + i) << "to " << author->lineNum << "\n";
            //std::cout<< regNumSize.first << "\n";
            //std::cout<< regNumSize.second << "\n";
          #endif
      }
  }

  static inline std::vector<Node*> get_reg_internal (int reg, int size)
  {
      int i = 0;
      std::vector<Node*> authors;
      int offset = 0;

      if (size == -1){
        size = 1;
        offset = 1;
      }

      for (i = 0; i < size; i++) {
          authors.push_back(shadow_reg_table[(reg * REG_SIZE + i)+offset]);
          #ifdef DEBUG_PRINT
            std::cout<< "GETTING shadow_reg_table at " << (reg * REG_SIZE + i) << "which is " << (shadow_reg_table[reg * REG_SIZE + i])->lineNum << "\n";
          #endif
      }
      #ifdef DEBUG_PRINT
        for (auto jt = std::begin(authors); jt != std::end(authors); ++jt){
                      std::cout<<"author is : " << (*jt)->lineNum  << "\n";
                    }
      #endif
      return authors;
  }

// trim from start (in place)
static inline void ltrim(std::string &s) {
    s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int ch) {
        return !std::isspace(ch);
    }));
}

// trim from end (in place)
static inline void rtrim(std::string &s) {
    s.erase(std::find_if(s.rbegin(), s.rend(), [](int ch) {
        return !std::isspace(ch);
    }).base(), s.end());
}

  void clear_reg (int reg, int size)
  {
      clear_reg_internal (reg, size);
  }

  void set_reg (int reg, int size, Node* author)
  {
      set_reg_internal (reg, size, author);
  }

  void set_dst_reg (std::string regName, Node* author)
  {
      std::pair<int, int> dstRegNumSize = checkForRegs(regName);
      set_reg(dstRegNumSize.first, dstRegNumSize.second, author);
  }

  //...

  std::string getStringWithinBrackets(std::string wholeInstructionString){
    std::sregex_iterator end;
    std::string bracketStr;
    //regex selects everything between square brackets
    //"word ptr [0xbfffef74]" IN
    //"[0xbfffef74]" OUT
    std::regex allInBrackets("(?=(\\[)).*");
    auto iterInBrack = std::sregex_iterator(wholeInstructionString.begin(), wholeInstructionString.end(), allInBrackets);
    while (iterInBrack != end) {
      std::smatch match = *iterInBrack;
      bracketStr = match.str();
      #ifdef DEBUG_PRINT
        std::cout << "memAddr:" << bracketStr << "\n";
      #endif
      iterInBrack++;
    }
    return bracketStr;
  }

  u_long hexStrToLong(std::string bracketStr, Node* p_tempNode, Node* p_rootNode){
    std::istringstream hexstr(bracketStr);
    u_long hexValue;
    if (bracketStr.compare("esp") == 0){
      hexValue = 96;
      handle_srcRegMemImm("esp",p_tempNode, p_rootNode);
      #ifdef DEBUG_PRINT
      std::cout<< "hexStrToLong has detected address [esp]! " << bracketStr << ", " << hexValue <<"\n";
      #endif
    }
    else{
      #ifdef DEBUG_PRINT
      std::cout<< "hexStrToLong has contents! " << bracketStr << ", " << hexValue <<"\n";
      #endif
      hexstr >> std::hex >> hexValue;
    }

    return hexValue;
  }

  int getMemSizeByte(std::string src, std::string bracketStr){
    std::string memSizeStr;
    memSizeStr = src.substr(0, src.find("ptr"));
    #ifdef DEBUG_PRINT
      std::cout << "getMemSize:" << memSizeStr << "\n";
    #endif

    ltrim(memSizeStr);
    rtrim(memSizeStr);
    int memSize;

    std::map<std::string, const int>::iterator iter2;
    iter2 = strSizeToByte.find(memSizeStr);
    if (iter2 != strSizeToByte.end()){
      memSize = (*iter2).second;
      #ifdef DEBUG_PRINT
        std::cout<<"srcmemSize:" << memSize << "\n";
      #endif
    }
    return memSize;
  }

  void set_src_mem(int memSizeBytes, u_long hexValue, Node* p_tempNode){
    int i;
    for (i=0; i<memSizeBytes; i++){
      std::map<u_long, Node*>::iterator it;
      it = mapMem.find(hexValue+i);
      //if the key actually exists in our map of [memoryAddress], authorNode
      if (it != mapMem.end()){
        Edge* p_tempInEdge = new Edge();
        Edge* p_tempOutEdge = new Edge();

        #ifdef DEBUG_PRINT
          std::cout<<(p_tempNode)->lineNum<< " p_tempNode->lineNum\n";
          std::cout<<((*it).second)->lineNum<< " authorNode in mapMem\n";
        #endif
        p_tempInEdge->start = (*it).second;
        p_tempInEdge->finish = p_tempNode;

        //add correct outEdge from previous register author to self current node
        p_tempOutEdge->start = (*it).second;
        p_tempOutEdge->finish = p_tempNode;

        p_tempNode->inEdges.push_back(p_tempInEdge);
        ((*it).second)->outEdges.push_back(p_tempOutEdge);
      }
    }
  }

  void set_src_root(Node* p_rootNode, Node* p_tempNode){
    Edge* p_tempInEdge = new Edge();
    Edge* p_tempOutEdge = new Edge();

    #ifdef DEBUG_PRINT
      std::cout<< "CONST SRC DETECTED! set_src_root() \n";
    #endif

    p_tempInEdge->start = p_rootNode;
    p_tempInEdge->finish = p_tempNode;
    p_tempOutEdge->start = p_rootNode;
    p_tempOutEdge->finish = p_tempNode;
    p_rootNode->outEdges.push_back(p_tempOutEdge);
    p_tempNode->inEdges.push_back(p_tempInEdge);
  }

  void set_src_reg(std::pair<int, int> srcRegNumSize, Node* p_tempNode){
  std::vector<Node*> regAuthors = get_reg_internal((srcRegNumSize.first),(srcRegNumSize.second));
  //if srcRegNumSize.first) is not EMPTY then it must be a valid register
  for (auto it = std::begin(regAuthors); it != std::end(regAuthors); ++it){
      //4-23-18
      Edge* p_tempInEdge = new Edge();
      Edge* p_tempOutEdge = new Edge();
      p_tempInEdge->start = (*it);
      p_tempInEdge->finish = p_tempNode;

      //add correct outEdge from previous register author to self current node
      p_tempOutEdge->start = (*it);
      p_tempOutEdge->finish = p_tempNode;

      p_tempNode->inEdges.push_back(p_tempInEdge);
      (*it)->outEdges.push_back(p_tempOutEdge);

      #ifdef DEBUG_PRINT
        std::cout<< "srcNoding lineNum " << (*it)->lineNum <<  " to " << p_tempNode->lineNum <<"\n";
        std::cout<<"p_tempInEdge->start : " << (*it)->lineNum  << "\n";
        std::cout<<"p_tempInEdge->finish is : " << p_tempNode->lineNum  << "\n";
        for (auto jt = std::begin((*it)->outEdges); jt != std::end((*it)->outEdges); ++jt){
          std::cout<<"outEdges for Node: " << ((*it))->lineNum << " is "  << ((*jt)->start)->lineNum << " to " << ((*jt)->finish)->lineNum  << "\n";
        }
        for (auto jt = std::begin(p_tempNode->inEdges); jt != std::end(p_tempNode->inEdges); ++jt){
          std::cout<<"inEdges for Node: " << " is "  << ((*jt)->start)->lineNum << " to " << ((*jt)->finish)->lineNum  << "\n";
        }
      #endif
    }
  }

  void set_src_regName(std::string regName, Node* p_tempNode){
  std::pair<int, int> srcRegNumSize = checkForRegs(regName);
  std::vector<Node*> regAuthors = get_reg_internal((srcRegNumSize.first),(srcRegNumSize.second));
  //if srcRegNumSize.first) is not EMPTY then it must be a valid register
  for (auto it = std::begin(regAuthors); it != std::end(regAuthors); ++it){
      //4-23-18
      Edge* p_tempInEdge = new Edge();
      Edge* p_tempOutEdge = new Edge();
      p_tempInEdge->start = (*it);
      p_tempInEdge->finish = p_tempNode;

      //add correct outEdge from previous register author to self current node
      p_tempOutEdge->start = (*it);
      p_tempOutEdge->finish = p_tempNode;

      p_tempNode->inEdges.push_back(p_tempInEdge);
      (*it)->outEdges.push_back(p_tempOutEdge);

      #ifdef DEBUG_PRINT
        std::cout<< "srcNoding lineNum " << (*it)->lineNum <<  " to " << p_tempNode->lineNum <<"\n";
        std::cout<<"p_tempInEdge->start : " << (*it)->lineNum  << "\n";
        std::cout<<"p_tempInEdge->finish is : " << p_tempNode->lineNum  << "\n";
        for (auto jt = std::begin((*it)->outEdges); jt != std::end((*it)->outEdges); ++jt){
          std::cout<<"outEdges for Node: " << ((*it))->lineNum << " is "  << ((*jt)->start)->lineNum << " to " << ((*jt)->finish)->lineNum  << "\n";
        }
        for (auto jt = std::begin(p_tempNode->inEdges); jt != std::end(p_tempNode->inEdges); ++jt){
          std::cout<<"inEdges for Node: " << " is "  << ((*jt)->start)->lineNum << " to " << ((*jt)->finish)->lineNum  << "\n";
        }
      #endif
    }
  }

  void set_dst_mem(int memSizeBytes, u_long hexValue, Node* p_tempNode){
    int i;
    for (i=0; i<memSizeBytes; i++){
                mapMem[(hexValue+i)] = p_tempNode;
              }
  }

  void set_dst_root(Node* p_rootNode, Node* p_tempNode){
    Edge* p_tempOutEdge = new Edge();

    #ifdef DEBUG_PRINT
      std::cout<< "CONST dst DETECTED! set_dst_root() \n";
    #endif

    p_tempOutEdge->start = p_tempNode;
    p_tempOutEdge->finish = p_rootNode;
    p_tempNode->outEdges.push_back(p_tempOutEdge);
  }

  static inline void set_clear_flags(Node* author, uint32_t set_flags, uint32_t clear_flags)
{
    if (set_flags != (uint32_t) -1 && clear_flags != (uint32_t) -1) {
  for (int i = 0; i<NUM_FLAGS; ++i) {
      if (set_flags & (1 << i)) {
          eflags_table[i] = author;
      }
      else if (clear_flags & (1 << i)) {
        //6-5-18 changed 'clearing' flags to be same as setting flags, because instructions that depended on flags that were cleared would break with a segfault when it comes to that 'cmov' sourcing from a flag that was cleared so it has no author. Maybe should change this to set author to p_RootNode.
          eflags_table[i] = author;
        //eflags_table[i] = 0;
      }
       }
    }
}

static inline void set_src_flags(Node* p_tempNode, uint32_t src_flags)
{

  if (src_flags != (uint32_t) -1) {
    for (int i = 0; i<NUM_FLAGS; ++i) {
      if (src_flags & (1 << i)) {
        Edge* p_tempInEdge = new Edge();
        Edge* p_tempOutEdge = new Edge();
        p_tempInEdge->start = (eflags_table[i]);
        p_tempInEdge->finish = p_tempNode;
        //add correct outEdge from previous register author to self current node
        p_tempOutEdge->start = (eflags_table[i]);
        p_tempOutEdge->finish = p_tempNode;
        p_tempNode->inEdges.push_back(p_tempInEdge);
        (eflags_table[i])->outEdges.push_back(p_tempOutEdge);
        #ifdef DEBUG_PRINT
        std::cout<<" i is: " << i  << "\n";
        #endif
      }
    }
  }
}

static inline std::string getMnemonic(std::string wholeInstructionString){
  std::string mnemonic;
  std::string istr;
  std::sregex_iterator end;

  std::regex allPreExtra("^.*(?=(\\/\\*))");
  auto iterPreExtra = std::sregex_iterator(wholeInstructionString.begin(), wholeInstructionString.end(), allPreExtra);
  if (iterPreExtra == end) {
    istr = wholeInstructionString.substr(0, wholeInstructionString.find("\\n"));
  }
  while (iterPreExtra != end) {
    std::smatch match = *iterPreExtra;
    istr = match.str();
    #ifdef DEBUG_PRINT
      std::cout << "regex2:" << match.str() << "\n";
    #endif
    iterPreExtra++;
  }

  //remove the quotes symbol char that leads the instruction string.
  istr = istr.substr(1, istr.size());

  mnemonic = istr.substr(0, istr.find(' '));
  ltrim(mnemonic);
  rtrim(mnemonic);
  #ifdef DEBUG_PRINT
    std::cout<<"istr:"<<istr<<"\n";
  #endif
    return mnemonic;
}

std::string getWholeInstruction (std::vector<std::string> instructionPieces){
  std::string wholeInstructionString = "";
  for (auto jt = std::begin(instructionPieces); jt != std::end(instructionPieces); ++jt){
                      wholeInstructionString = wholeInstructionString + (*jt);
                    }
  return wholeInstructionString;
}

std::vector<std::string> getInstrPieces (std::string wholeInstructionString)
{
  std::string mnemonic;
  std::string istr;
  std::string dst;
  std::string src;
  std::string fourth;

  std::sregex_iterator end;

  std::regex allPreExtra("^.*(?=(\\/\\*))");
  auto iterPreExtra = std::sregex_iterator(wholeInstructionString.begin(), wholeInstructionString.end(), allPreExtra);
  if (iterPreExtra == end) {
    istr = wholeInstructionString.substr(0, wholeInstructionString.find("\\n"));
  }
  while (iterPreExtra != end) {
    std::smatch match = *iterPreExtra;
    istr = match.str();
    #ifdef DEBUG_PRINT
      std::cout << "regex2:" << match.str() << "\n";
    #endif
    iterPreExtra++;
  }

  //remove the quotes symbol char that leads the instruction string.
  istr = istr.substr(1, istr.size());

  mnemonic = istr.substr(0, istr.find(' '));
  ltrim(mnemonic);
  rtrim(mnemonic);

  #ifdef DEBUG_PRINT
    std::cout<<"(getInstrPieces)istr:"<<istr<<"\n";
  #endif

  dst = istr.substr((istr.find(mnemonic)+mnemonic.size()+1), (istr.find(',')-mnemonic.size()-1));

  src = istr.substr((istr.find(',')+1), (istr.size()-2));
  ltrim(src);
  //std::cout<<"dst,src:"<<dst<< ','<<src<<"\n";
  fourth = src.substr((src.find(',')+1), (src.size()-2));
  ltrim(fourth);

  //split this 'src' string one more time on the comma
  //this is for 4 argument (including mnemonic) instructions
  if((src.find(',')) != std::string::npos){
    src = src.substr(0, (src.find(',')));
  }

  //trim off pre AND post whitespace from the registerName string
  ltrim(src);
  ltrim(dst);
  ltrim(mnemonic);
  ltrim(fourth);
  rtrim(src);
  rtrim(dst);
  rtrim(mnemonic);
  rtrim(fourth);
  #ifdef DEBUG_PRINT
    std::cout<<"mnemonic Arg: "<<mnemonic<<"\n";
    std::cout<<"dst Arg: "<<dst<<"\n";
    std::cout<<"src Arg: "<<src<<"\n";
    std::cout<<"fourth Arg: "<<fourth<<"\n";
  #endif

  std::vector<std::string> instrPieces;
  instrPieces.push_back(mnemonic);
  instrPieces.push_back(dst);
  instrPieces.push_back(src);
  instrPieces.push_back(fourth);
  return instrPieces;
}

void instrument_div (std::string wholeInstructionString,  uint32_t set_flags, uint32_t clear_flags, Node* p_tempNode, Node* p_rootNode)
{

  std::vector<std::string> instrPieces = getInstrPieces(wholeInstructionString);

  std::string mnemonic = instrPieces.at(0);
  std::string dst = instrPieces.at(1);
  std::string dstB = instrPieces.at(1);
  std::string src = instrPieces.at(2);
  //div instruction only has one argument, the src, aka divisor. the dividend is implicit AX, DX:AX, EDX:EAX
  //the div instr stores the result in the AX (AH:AL), DX:AX, or EDX:EAX registers.
  src = instrPieces.at(1);

  std::pair<int, int> srcRegNumSize = checkForRegs(src);
  std::vector<Node*> regAuthors = get_reg_internal((srcRegNumSize.first),(srcRegNumSize.second));

  #ifdef DEBUG_PRINT
    for (auto jt = std::begin(instrPieces); jt != std::end(instrPieces); ++jt){
              std::cout<<"[instrument_div]srcRegNumSize.first, .second is : " << (srcRegNumSize.first) << ", "  << (srcRegNumSize.second) << "\n";
            }
    std::cout<<"mnemonic is: " << mnemonic  << "\n";
    std::cout<<"dst is : " << dst  << "\n";
    std::cout<<"src is : " << src  << "\n";

    for (auto jt = std::begin(regAuthors); jt != std::end(regAuthors); ++jt){
              std::cout<<"regAuthor is : " << (*jt)->lineNum  << "\n";
            }
  #endif

  #ifdef DEBUG_PRINT
    std::cout<< "regAuthors.empty() is " << regAuthors.empty() << "\n";
    std::cout<< "srcRegNumSize.first is " << srcRegNumSize.first << "\n";
  #endif

  //if there is a src register, set the appropriate edges to the previous author of that register
  if(srcRegNumSize.first){
    set_src_reg(srcRegNumSize, p_tempNode);
    //set the dividend register according to divisor register size
    switch (srcRegNumSize.second)
    {
      case 4:
        dst = "edx";
        dstB = "eax";
        break;
      case 2:
        dst = "dx";
        dstB = "ax";
        break;
      case 1:
      case -1:
        dst = "ah";
        dstB = "al";
        break;
    }
  }
  //else must be a const src or memory src
  else{
    std::string bracketStr;
    std::string memAddrStr;
    bracketStr = getStringWithinBrackets(src);

    //take the bracketString of a memory address src, [0xbfffef74]
    //and convert the bracketStr to a u_long hexvalue of the memory address, 3221221236
    if(bracketStr.size() > 0){
      int memSizeBytes = getMemSizeByte(src,bracketStr);
      //remove the brackets from the string
      memAddrStr = bracketStr.substr(1, (bracketStr.size()-2));
      u_long hexValue = hexStrToLong(memAddrStr, p_tempNode, p_rootNode);
      set_src_mem(memSizeBytes, hexValue, p_tempNode);
      switch (memSizeBytes)
      {
        case 4:
          dst = "edx";
          dstB = "eax";
          break;
        case 2:
          dst = "dx";
          dstB = "ax";
          break;
        case 1:
        case -1:
          dst = "ah";
          dstB = "al";
          break;
      }

    }
    //else if (bracketStr.size() < 0) then must be a constant src like "17"
    //so create an OUTedge from the rootNode to the current tempInstruction node;
    //and create an INedge from the rootNode to the current tempInstruction node;
    else{
      set_src_root(p_rootNode, p_tempNode);
      //6-1-18
      //temp hacky assumption that all constant srcs are 32 bit args
      //the x86 'div' instruction never directly srcs in immediate constant values so this code should never be used.
      dst = "edx";
      dstB = "eax";
    }
  }

  //...
  std::pair<int, int> dstRegNumSize = checkForRegs(dst);
  set_src_reg(dstRegNumSize, p_tempNode);
  set_clear_flags(p_tempNode, set_flags, clear_flags);

  std::pair<int, int> dstBRegNumSize = checkForRegs(dstB);
  set_src_reg(dstBRegNumSize, p_tempNode);

   //if (dstRegNumSize.first) is not NULL then it must be a valid register
  if(dstRegNumSize.first){
    set_reg((dstRegNumSize.first), (dstRegNumSize.second), p_tempNode);
  }

   //if (dstBRegNumSize.first) is not NULL then it must be a valid register
  if(dstBRegNumSize.first){
    set_reg((dstBRegNumSize.first), (dstBRegNumSize.second), p_tempNode);
  }
}

void handle_srcRegMemImm (std::string src, Node* p_tempNode, Node* p_rootNode){
  #ifdef DEBUG_PRINT
  std::cout<< "(handle_srcRegMemImm) src is : " << src << "\n";
  std::cout<< "srcRegNumSize.first, srcRegNumSize.second is " << srcRegNumSize.first << ", " <<srcRegNumSize.second << "\n";
  #endif
  std::pair<int, int> srcRegNumSize = checkForRegs(src);

  #ifdef DEBUG_PRINT
    std::vector<Node*> regAuthors = get_reg_internal((srcRegNumSize.first),(srcRegNumSize.second));
    for (auto jt = std::begin(regAuthors); jt != std::end(regAuthors); ++jt){
              std::cout<<"regAuthor is : " << (*jt)->lineNum  << "\n";
            }
  #endif

  #ifdef DEBUG_PRINT
    std::cout<< "regAuthors.empty() is " << regAuthors.empty() << "\n";
    std::cout<< "srcRegNumSize.first is " << srcRegNumSize.first << "\n";
  #endif

  //if there is a src register, set the appropriate edges to the previous author of that register
  if(srcRegNumSize.first){
    set_src_reg(srcRegNumSize, p_tempNode);
  }
  //else must be a const src or memory src
  else{
    std::string bracketStr;
    std::string memAddrStr;
    bracketStr = getStringWithinBrackets(src);

    //take the bracketString of a memory address src, [0xbfffef74]
    //and convert the bracketStr to a u_long hexvalue of the memory address, 3221221236
    if(bracketStr.size() > 0){
      int memSizeBytes = getMemSizeByte(src,bracketStr);
      //remove the brackets from the string
      memAddrStr = bracketStr.substr(1, (bracketStr.size()-2));
      u_long hexValue = hexStrToLong(memAddrStr, p_tempNode, p_rootNode);
      set_src_mem(memSizeBytes, hexValue, p_tempNode);
    }
    //else if (bracketStr.size() < 0) then must be a constant src like "17"
    //so create an OUTedge from the rootNode to the current tempInstruction node;
    //and create an INedge from the rootNode to the current tempInstruction node;
    else{
      set_src_root(p_rootNode, p_tempNode);
    }
  }
}

void handle_dstRegMemImm (std::string dst, Node* p_tempNode, Node* p_rootNode){
  #ifdef DEBUG_PRINT
  std::cout<< "(handle_dstRegMemImm) dst is : " << dst << "\n";
  #endif
  std::pair<int, int> dstRegNumSize = checkForRegs(dst);

   //if (dstRegNumSize.first) is not NULL then it must be a valid register
  if(dstRegNumSize.first){
    set_reg((dstRegNumSize.first), (dstRegNumSize.second), p_tempNode);
  }
  else{
    //else must be a const or memory dst
    //handle memory dst
    //1 byte = 8 bits
    //word = 2 bytes = 16 bits
    //double word = 4 bytes = 32 bits
    //xmm word = 16 bytes = 144 bits
    std::string bracketStr;
    std::string memAddrStr;
    bracketStr = getStringWithinBrackets(dst);

    //if the dst is a memory range, then set the new author to be current Instruction node 'p_tempNode'
    if(bracketStr.size() > 0){
      int memSizeBytes = getMemSizeByte(dst,bracketStr);
      //remove the brackets from the string
      memAddrStr = bracketStr.substr(1, (bracketStr.size()-2));
      u_long hexValue = hexStrToLong(memAddrStr, p_tempNode, p_rootNode);
      set_dst_mem(memSizeBytes, hexValue, p_tempNode);

    }
    else{
      //else if (dstRegNumSize.first) is equal to "null" then must be a constant like "17"
      //so create an OUTedge from the rootNode to the current tempInstruction node;
      //and create an INedge from the rootNode to the current tempInstruction node;
      set_dst_root(p_rootNode, p_tempNode);
    }
  }
}

void instrument_onedst_twosrc(std::string wholeInstructionString,  uint32_t set_flags, uint32_t clear_flags, Node* p_tempNode, Node* p_rootNode)
{

  std::vector<std::string> instrPieces = getInstrPieces(wholeInstructionString);

  std::string mnemonic = instrPieces.at(0);
  std::string dst = instrPieces.at(1);
  std::string src = instrPieces.at(2);
  std::string srcB = instrPieces.at(3);

  handle_srcRegMemImm(src, p_tempNode, p_rootNode);
  handle_srcRegMemImm(srcB, p_tempNode, p_rootNode);

  set_clear_flags(p_tempNode, set_flags, clear_flags);
  handle_dstRegMemImm(dst, p_tempNode, p_rootNode);
}

void instrument_eflagsdst_twosrc(std::string wholeInstructionString,  uint32_t set_flags, uint32_t clear_flags, Node* p_tempNode, Node* p_rootNode)
{

  std::vector<std::string> instrPieces = getInstrPieces(wholeInstructionString);

  std::string mnemonic = instrPieces.at(0);
  //in CMP/TEST instructions the two args are two srcs. The dst is setting the EFLAGS register.
  //so src1 in this case is instrPieces.at(1)
  //and src2 is instrPieces.at(2)
  std::string src = instrPieces.at(1);
  std::string srcB = instrPieces.at(2);

  handle_srcRegMemImm(src, p_tempNode, p_rootNode);
  handle_srcRegMemImm(srcB, p_tempNode, p_rootNode);

  set_clear_flags(p_tempNode, set_flags, clear_flags);
}

void instrument_cmp_or_test (std::string wholeInstructionString,  uint32_t set_flags, uint32_t clear_flags, Node* p_tempNode, Node* p_rootNode)
{

  instrument_eflagsdst_twosrc(wholeInstructionString, set_flags, clear_flags, p_tempNode, p_rootNode);
}

void instrument_imul (std::string wholeInstructionString,  uint32_t set_flags, uint32_t clear_flags, Node* p_tempNode, Node* p_rootNode)
{

  std::vector<std::string> instrPieces = getInstrPieces(wholeInstructionString);

  //commaCount of 0 is imul instruction with a single arg, is similar to mul instruction
  //commaCount of 1 is imul with two args, dest = dest * src
  //commaCount of 2 is imul with three args, dest = src * immediate
  size_t commaCount = std::count(wholeInstructionString.begin(), wholeInstructionString.end(), ',');
  #ifdef DEBUG_PRINT
  std::cout << "commaCount is: " << commaCount << "\n";
  #endif

  switch(commaCount){
    case 0:
      instrument_mul(wholeInstructionString, set_flags, clear_flags, p_tempNode, p_rootNode);
      break;
    case 1:
      instrument_addorsub(wholeInstructionString, set_flags, clear_flags, p_tempNode, p_rootNode);
      break;
    case 2:
      instrument_onedst_twosrc(wholeInstructionString, set_flags, clear_flags, p_tempNode, p_rootNode);
      break;
    default:
    std::cout<< "[ERROR]instrument_imul cant handle this instruction " << wholeInstructionString << "\n";
  }
}

void instrument_mul (std::string wholeInstructionString,  uint32_t set_flags, uint32_t clear_flags, Node* p_tempNode, Node* p_rootNode)
{

  std::vector<std::string> instrPieces = getInstrPieces(wholeInstructionString);

  std::string mnemonic = instrPieces.at(0);
  std::string dst = instrPieces.at(1);
  std::string dstB = instrPieces.at(1);
  std::string src = instrPieces.at(2);
  //mul instruction only has one argument, the src. the dst is implicit AL, AX, EAX
  //the mul instr stores the result in the AX (AH:AL), DX:AX, or EDX:EAX registers.
  src = instrPieces.at(1);

  std::pair<int, int> srcRegNumSize = checkForRegs(src);
  std::vector<Node*> regAuthors = get_reg_internal((srcRegNumSize.first),(srcRegNumSize.second));

  #ifdef DEBUG_PRINT
  for (auto jt = std::begin(instrPieces); jt != std::end(instrPieces); ++jt){
              std::cout<<"[instrument_mul]srcRegNumSize.first, .second is : " << (srcRegNumSize.first) << ", "  << (srcRegNumSize.second) << "\n";
            }

    for (auto jt = std::begin(regAuthors); jt != std::end(regAuthors); ++jt){
              std::cout<<"regAuthor is : " << (*jt)->lineNum  << "\n";
            }
  #endif

  #ifdef DEBUG_PRINT
    std::cout<< "regAuthors.empty() is " << regAuthors.empty() << "\n";
    std::cout<< "srcRegNumSize.first is " << srcRegNumSize.first << "\n";
  #endif

  //if there is a src register, set the appropriate edges to the previous author of that register
  if(srcRegNumSize.first){
    set_src_reg(srcRegNumSize, p_tempNode);
    //set the dst register according to src register size
    switch (srcRegNumSize.second)
    {
      case 4:
        dst = "edx";
        dstB = "eax";
        break;
      case 2:
        dst = "dx";
        dstB = "ax";
        break;
      case 1:
      case -1:
        dst = "ax";
        dstB = "al";
        break;
    }
  }
  //else must be a const src or memory src
  else{
    std::string bracketStr;
    std::string memAddrStr;
    bracketStr = getStringWithinBrackets(src);

    //take the bracketString of a memory address src, [0xbfffef74]
    //and convert the bracketStr to a u_long hexvalue of the memory address, 3221221236
    if(bracketStr.size() > 0){
      int memSizeBytes = getMemSizeByte(src,bracketStr);
      //remove the brackets from the string
      memAddrStr = bracketStr.substr(1, (bracketStr.size()-2));
      u_long hexValue = hexStrToLong(memAddrStr, p_tempNode, p_rootNode);
      set_src_mem(memSizeBytes, hexValue, p_tempNode);
      switch (memSizeBytes)
      {
        case 4:
          dst = "edx";
          dstB = "eax";
          break;
        case 2:
          dst = "dx";
          dstB = "ax";
          break;
        case 1:
        case -1:
          dst = "ax";
          dstB = "al";
          break;
      }

    }
    //else if (bracketStr.size() < 0) then must be a constant src like "17"
    //so create an OUTedge from the rootNode to the current tempInstruction node;
    //and create an INedge from the rootNode to the current tempInstruction node;
    else{
      set_src_root(p_rootNode, p_tempNode);
      //6-1-18
      //temp hacky assumption that all constant srcs are 32 bit args
      //the x86 'mul' instruction never directly srcs in immediate constant values so this code should never be used.
      dst = "edx";
      dstB = "eax";
    }
  }

  //...
  set_clear_flags(p_tempNode, set_flags, clear_flags);

  std::pair<int, int> dstRegNumSize = checkForRegs(dst);
  std::pair<int, int> dstBRegNumSize = checkForRegs(dstB);
  set_src_reg(dstBRegNumSize, p_tempNode);

   //if (dstRegNumSize.first) is not NULL then it must be a valid register
  if(dstRegNumSize.first){
    set_reg((dstRegNumSize.first), (dstRegNumSize.second), p_tempNode);
  }

   //if (dstBRegNumSize.first) is not NULL then it must be a valid register
  if(dstBRegNumSize.first){
    set_reg((dstBRegNumSize.first), (dstBRegNumSize.second), p_tempNode);
  }

#ifdef DEBUG_PRINT
  std::cout<<"mnemonic is: " << mnemonic  << "\n";
    std::cout<<"dst is : " << dst  << "\n";
    std::cout<<"dstB is : " << dstB  << "\n";
    std::cout<<"src is : " << src  << "\n";
  #endif

}

void instrument_set (std::string wholeInstructionString,  uint32_t set_flags, uint32_t clear_flags, Node* p_tempNode, Node* p_rootNode)
{
  std::vector<std::string> instrPieces = getInstrPieces(wholeInstructionString);

  std::string mnemonic = instrPieces.at(0);
  std::string dst = instrPieces.at(1);
  handle_dstRegMemImm(dst, p_tempNode, p_rootNode);
}

void instrument_addorsub (std::string wholeInstructionString,  uint32_t set_flags, uint32_t clear_flags, Node* p_tempNode, Node* p_rootNode)
{

  std::vector<std::string> instrPieces = getInstrPieces(wholeInstructionString);

  std::string mnemonic = instrPieces.at(0);
  std::string dst = instrPieces.at(1);
  std::string src = instrPieces.at(2);

  std::pair<int, int> srcRegNumSize = checkForRegs(src);
  std::vector<Node*> regAuthors = get_reg_internal((srcRegNumSize.first),(srcRegNumSize.second));

  #ifdef DEBUG_PRINT
    for (auto jt = std::begin(regAuthors); jt != std::end(regAuthors); ++jt){
              std::cout<<"regAuthor is : " << (*jt)->lineNum  << "\n";
            }
  #endif

  #ifdef DEBUG_PRINT
    std::cout<< "regAuthors.empty() is " << regAuthors.empty() << "\n";
    std::cout<< "srcRegNumSize.first is " << srcRegNumSize.first << "\n";
  #endif

  //if there is a src register, set the appropriate edges to the previous author of that register
  if(srcRegNumSize.first){
    set_src_reg(srcRegNumSize, p_tempNode);
  }
  //else must be a const src or memory src
  else{
    std::string bracketStr;
    std::string memAddrStr;
    bracketStr = getStringWithinBrackets(src);

    //take the bracketString of a memory address src, [0xbfffef74]
    //and convert the bracketStr to a u_long hexvalue of the memory address, 3221221236
    if(bracketStr.size() > 0){
      int memSizeBytes = getMemSizeByte(src,bracketStr);
      //remove the brackets from the string
      memAddrStr = bracketStr.substr(1, (bracketStr.size()-2));
      u_long hexValue = hexStrToLong(memAddrStr, p_tempNode, p_rootNode);
      set_src_mem(memSizeBytes, hexValue, p_tempNode);
    }
    //else if (bracketStr.size() < 0) then must be a constant src like "17"
    //so create an OUTedge from the rootNode to the current tempInstruction node;
    //and create an INedge from the rootNode to the current tempInstruction node;
    else{
      set_src_root(p_rootNode, p_tempNode);
    }
  }
  //...
  std::pair<int, int> dstRegNumSize = checkForRegs(dst);
  //6-17 Possible Bug! this line "set_src_reg(dstRegNumSize, p_tempNode)" should be moved into the "if(dstRegNumSize.first){" scope below?
  set_src_reg(dstRegNumSize, p_tempNode);
  set_clear_flags(p_tempNode, set_flags, clear_flags);

   //if (dstRegNumSize.first) is not NULL then it must be a valid register
  if(dstRegNumSize.first){
    set_reg((dstRegNumSize.first), (dstRegNumSize.second), p_tempNode);
  }
  else{
    //else must be a const or memory dst
    //handle memory dst
    //1 byte = 8 bits
    //word = 2 bytes = 16 bits
    //double word = 4 bytes = 32 bits
    //xmm word = 16 bytes = 144 bits
    std::string bracketStr;
    std::string memAddrStr;
    bracketStr = getStringWithinBrackets(dst);

    //if the dst is a memory range, then set the new author to be current Instruction node 'p_tempNode'
    if(bracketStr.size() > 0){
      int memSizeBytes = getMemSizeByte(dst,bracketStr);
      //remove the brackets from the string
      memAddrStr = bracketStr.substr(1, (bracketStr.size()-2));
      u_long hexValue = hexStrToLong(memAddrStr, p_tempNode, p_rootNode);
      set_src_mem(memSizeBytes, hexValue, p_tempNode);
      set_dst_mem(memSizeBytes, hexValue, p_tempNode);

    }
    else{
      //else if (dstRegNumSize.first) is equal to "null" then must be a constant like "17"
      //so create an OUTedge from the rootNode to the current tempInstruction node;
      //and create an INedge from the rootNode to the current tempInstruction node;
      set_dst_root(p_rootNode, p_tempNode);
    }
  }
}

void instrument_xchg (std::string wholeInstructionString,  uint32_t set_flags, uint32_t clear_flags, Node* p_tempNode, Node* p_rootNode)
{

  std::vector<std::string> instrPieces = getInstrPieces(wholeInstructionString);

  std::string mnemonic = instrPieces.at(0);
  std::string dst = instrPieces.at(1);
  std::string src = instrPieces.at(2);

  std::pair<int, int> srcRegNumSize = checkForRegs(src);
  std::vector<Node*> regAuthors = get_reg_internal((srcRegNumSize.first),(srcRegNumSize.second));

  #ifdef DEBUG_PRINT
    for (auto jt = std::begin(regAuthors); jt != std::end(regAuthors); ++jt){
              std::cout<<"regAuthor is : " << (*jt)->lineNum  << "\n";
            }
  #endif

  #ifdef DEBUG_PRINT
    std::cout<< "regAuthors.empty() is " << regAuthors.empty() << "\n";
    std::cout<< "srcRegNumSize.first is " << srcRegNumSize.first << "\n";
  #endif

  //if there is a src register, set the appropriate edges to the previous author of that register
  if(srcRegNumSize.first){
    set_src_reg(srcRegNumSize, p_tempNode);
  }
  //else must be a const src or memory src
  else{
    std::string bracketStr;
    std::string memAddrStr;
    bracketStr = getStringWithinBrackets(src);

    //take the bracketString of a memory address src, [0xbfffef74]
    //and convert the bracketStr to a u_long hexvalue of the memory address, 3221221236
    if(bracketStr.size() > 0){
      int memSizeBytes = getMemSizeByte(src,bracketStr);
      //remove the brackets from the string
      memAddrStr = bracketStr.substr(1, (bracketStr.size()-2));
      u_long hexValue = hexStrToLong(memAddrStr, p_tempNode, p_rootNode);
      set_src_mem(memSizeBytes, hexValue, p_tempNode);
    }
    //else if (bracketStr.size() < 0) then must be a constant src like "17"
    //so create an OUTedge from the rootNode to the current tempInstruction node;
    //and create an INedge from the rootNode to the current tempInstruction node;
    else{
      set_src_root(p_rootNode, p_tempNode);
    }
  }
  //...
  std::pair<int, int> dstRegNumSize = checkForRegs(dst);
  set_src_reg(dstRegNumSize, p_tempNode);
  set_clear_flags(p_tempNode, set_flags, clear_flags);

   //if (dstRegNumSize.first) is not NULL then it must be a valid register
  if(dstRegNumSize.first){
    set_reg((dstRegNumSize.first), (dstRegNumSize.second), p_tempNode);
  }
  else{
    //else must be a const or memory dst
    //handle memory dst
    //1 byte = 8 bits
    //word = 2 bytes = 16 bits
    //double word = 4 bytes = 32 bits
    //xmm word = 16 bytes = 144 bits
    std::string bracketStr;
    std::string memAddrStr;
    bracketStr = getStringWithinBrackets(dst);

    //if the dst is a memory range, then set the new author to be current Instruction node 'p_tempNode'
    if(bracketStr.size() > 0){
      int memSizeBytes = getMemSizeByte(dst,bracketStr);
      //remove the brackets from the string
      memAddrStr = bracketStr.substr(1, (bracketStr.size()-2));
      u_long hexValue = hexStrToLong(memAddrStr, p_tempNode, p_rootNode);
      set_src_mem(memSizeBytes, hexValue, p_tempNode);
      set_dst_mem(memSizeBytes, hexValue, p_tempNode);

    }
    else{
      //else if (dstRegNumSize.first) is equal to "null" then must be a constant like "17"
      //so create an OUTedge from the rootNode to the current tempInstruction node;
      //and create an INedge from the rootNode to the current tempInstruction node;
      set_dst_root(p_rootNode, p_tempNode);
    }
  }

     //if (srcRegNumSize.first) is not NULL then it must be a valid register
  if(srcRegNumSize.first){
    set_reg((srcRegNumSize.first), (srcRegNumSize.second), p_tempNode);
  }
  else{
    //else must be a const or memory dst
    //handle memory dst
    //1 byte = 8 bits
    //word = 2 bytes = 16 bits
    //double word = 4 bytes = 32 bits
    //xmm word = 16 bytes = 144 bits
    std::string bracketStr;
    std::string memAddrStr;
    bracketStr = getStringWithinBrackets(dst);

    //if the dst is a memory range, then set the new author to be current Instruction node 'p_tempNode'
    if(bracketStr.size() > 0){
      int memSizeBytes = getMemSizeByte(dst,bracketStr);
      //remove the brackets from the string
      memAddrStr = bracketStr.substr(1, (bracketStr.size()-2));
      u_long hexValue = hexStrToLong(memAddrStr, p_tempNode, p_rootNode);
      set_dst_mem(memSizeBytes, hexValue, p_tempNode);

    }
    else{
      //else if (srcRegNumSize.first) is equal to "null" then must be a constant like "17"
      //so create an OUTedge from the rootNode to the current tempInstruction node;
      //and create an INedge from the rootNode to the current tempInstruction node;
      set_dst_root(p_rootNode, p_tempNode);
    }
  }
}

void instrument_push (std::string wholeInstructionString,  uint32_t set_flags, uint32_t clear_flags, Node* p_tempNode, Node* p_rootNode)
{
  set_src_regName("esp", p_tempNode);
  std::vector<std::string> instrPieces = getInstrPieces(wholeInstructionString);

  std::string mnemonic = instrPieces.at(0);
  std::string src = instrPieces.at(1);

  handle_srcRegMemImm(src, p_tempNode, p_rootNode);
  set_dst_reg("esp", p_tempNode);
  #ifdef DEBUG_PRINT
  std::cout<<"(instrument_push)src is : " << src  << "\n";
  std::cout  << "\n";
  #endif

}

void instrument_pcmpistri (std::string wholeInstructionString,  uint32_t set_flags, uint32_t clear_flags, Node* p_tempNode, Node* p_rootNode)
{
  set_clear_flags(p_tempNode, set_flags, clear_flags);
  std::vector<std::string> instrPieces = getInstrPieces(wholeInstructionString);

  std::string mnemonic = instrPieces.at(0);
  std::string src = instrPieces.at(1);
  std::string srcB = instrPieces.at(2);

  handle_srcRegMemImm(src, p_tempNode, p_rootNode);
  handle_srcRegMemImm(srcB, p_tempNode, p_rootNode);
  set_dst_reg("ecx", p_tempNode);
  #ifdef DEBUG_PRINT
  std::cout<<"(instrument_pcmpistri)src is : " << src  << "\n";
  std::cout<<"(instrument_pcmpistri)srcB is : " << srcB  << "\n";
  std::cout  << "\n";
  #endif

}

void instrument_pop (std::string wholeInstructionString,  uint32_t set_flags, uint32_t clear_flags, Node* p_tempNode, Node* p_rootNode)
{
  set_src_regName("esp", p_tempNode);
  std::vector<std::string> instrPieces = getInstrPieces(wholeInstructionString);

  std::string mnemonic = instrPieces.at(0);
  std::string dst = instrPieces.at(1);

  handle_dstRegMemImm(dst, p_tempNode, p_rootNode);
  set_dst_reg("esp", p_tempNode);
  #ifdef DEBUG_PRINT
  std::cout<<"(instrument_pop)dst is : " << dst  << "\n";
  std::cout  << "\n";
  #endif
}

void instrument_neg_not (std::string wholeInstructionString,  uint32_t set_flags, uint32_t clear_flags, Node* p_tempNode, Node* p_rootNode)
{
  set_clear_flags(p_tempNode, set_flags, clear_flags);
  std::vector<std::string> instrPieces = getInstrPieces(wholeInstructionString);

  std::string mnemonic = instrPieces.at(0);
  std::string src = instrPieces.at(1);

  handle_srcRegMemImm(src, p_tempNode, p_rootNode);
  handle_dstRegMemImm(src, p_tempNode, p_rootNode);
  #ifdef DEBUG_PRINT
  std::cout<<"(instrument_neg_not)src is : " << src  << "\n";
  std::cout  << "\n";
  #endif
}

void instrument_rep_movsd (std::string wholeInstructionString,  uint32_t set_flags, uint32_t clear_flags, Node* p_tempNode, Node* p_rootNode)
{
  set_src_flags(p_tempNode, DF_FLAG);
  set_src_regName("ecx", p_tempNode);

  handle_srcRegMemImm("ds", p_tempNode, p_rootNode);
  handle_srcRegMemImm("esi", p_tempNode, p_rootNode);
  handle_dstRegMemImm("esi", p_tempNode, p_rootNode);
  handle_dstRegMemImm("edi", p_tempNode, p_rootNode);

  #ifdef DEBUG_PRINT
  std::cout<<"(instrument_rep_movsd)src is : " << "ds"  << "\n";
  std::cout  << "\n";
  #endif
}

void instrument_repne_scasb (std::string wholeInstructionString,  uint32_t set_flags, uint32_t clear_flags, Node* p_tempNode, Node* p_rootNode)
{
  set_src_flags(p_tempNode, DF_FLAG|ZF_FLAG);
  set_src_regName("ecx", p_tempNode);

  handle_srcRegMemImm("es", p_tempNode, p_rootNode);
  handle_srcRegMemImm("edi", p_tempNode, p_rootNode);
  handle_srcRegMemImm("al", p_tempNode, p_rootNode);
  handle_dstRegMemImm("edi", p_tempNode, p_rootNode);

  set_clear_flags(p_tempNode, set_flags, clear_flags);

  #ifdef DEBUG_PRINT
  std::cout<<"(instrument_repne_scasb)src is : " << "es"  << "\n";
  std::cout  << "\n";
  #endif
}

void instrument_cwde (std::string wholeInstructionString,  uint32_t set_flags, uint32_t clear_flags, Node* p_tempNode, Node* p_rootNode)
{
  handle_srcRegMemImm("ax", p_tempNode, p_rootNode);
  handle_dstRegMemImm("eax", p_tempNode, p_rootNode);

  #ifdef DEBUG_PRINT
  std::cout<<"(instrument_cwde)src is : " << "ax"  << "\n";
  std::cout  << "\n";
  #endif
}

void instrument_mov (std::string wholeInstructionString,  uint32_t set_flags, uint32_t clear_flags, Node* p_tempNode, Node* p_rootNode)
{

  std::vector<std::string> instrPieces = getInstrPieces(wholeInstructionString);

  std::string mnemonic = instrPieces.at(0);
  std::string dst = instrPieces.at(1);
  std::string src = instrPieces.at(2);

  #ifdef DEBUG_PRINT
    std::cout<<"mnemonic is: " << mnemonic  << "\n";
    std::cout<<"dst is : " << dst  << "\n";
    std::cout<<"src is : " << src  << "\n";
  #endif

  set_clear_flags(p_tempNode, set_flags, clear_flags);

  std::pair<int, int> srcRegNumSize = checkForRegs(src);
  std::vector<Node*> regAuthors = get_reg_internal((srcRegNumSize.first),(srcRegNumSize.second));

  #ifdef DEBUG_PRINT
    for (auto jt = std::begin(regAuthors); jt != std::end(regAuthors); ++jt){
              std::cout<<"regAuthor is : " << (*jt)->lineNum  << "\n";
            }
  #endif

  #ifdef DEBUG_PRINT
    std::cout<< "regAuthors.empty() is " << regAuthors.empty() << "\n";
    std::cout<< "srcRegNumSize.first is " << srcRegNumSize.first << "\n";
  #endif

  int memSizeBytes = 0;
  u_long hexValue = 0;

  //if there is a src register, set the appropriate edges to the previous author of that register
  if(srcRegNumSize.first){
    set_src_reg(srcRegNumSize, p_tempNode);
  }
  //else must be a const src or memory src
  else{
    std::string bracketStr;
    std::string memAddrStr;
    bracketStr = getStringWithinBrackets(src);

    //take the bracketString of a memory address src, [0xbfffef74]
    //and convert the bracketStr to a u_long hexvalue of the memory address, 3221221236
    if(bracketStr.size() > 0){
      memSizeBytes = getMemSizeByte(src,bracketStr);
      //remove the brackets from the string
      memAddrStr = bracketStr.substr(1, (bracketStr.size()-2));
      hexValue = hexStrToLong(memAddrStr, p_tempNode, p_rootNode);
      set_src_mem(memSizeBytes, hexValue, p_tempNode);
    }
    //else if (bracketStr.size() < 0) then must be a constant src like "17"
    //so create an OUTedge from the rootNode to the current tempInstruction node;
    //and create an INedge from the rootNode to the current tempInstruction node;
    else{
      set_src_root(p_rootNode, p_tempNode);
    }
  }
  //...
  std::pair<int, int> dstRegNumSize = checkForRegs(dst);

   //if (dstRegNumSize.first) is not NULL then it must be a valid register
  if(dstRegNumSize.first){
    #ifdef VAL_EQV
      //if srcMem and dstReg, then get the last author of that memory range and check if the dst Reg already has that same authors. If yes dstReg has the same authors as the memory range, then mark instruction as EXTRA=1"
       if (memSizeBytes)
       {
         if(hexValue){
           std::vector<Node*> dstRegAuthors = get_reg_internal((dstRegNumSize.first),(dstRegNumSize.second));
           if (dstRegAuthors == mapMemValue[hexValue])
           {
             p_tempNode->extra = 1;
           }
         }

       }
     #endif
     //if the instruction node is not extra then set the reg with the p_tempNode as the new author.
     if ((p_tempNode-> extra) == 0){
      set_reg((dstRegNumSize.first), (dstRegNumSize.second), p_tempNode);
     }

  }
  else{
    //else must be a const or memory dst
    //handle memory dst
    //1 byte = 8 bits
    //word = 2 bytes = 16 bits
    //double word = 4 bytes = 32 bits
    //xmm word = 16 bytes = 144 bits
    std::string bracketStr;
    std::string memAddrStr;
    bracketStr = getStringWithinBrackets(dst);

    //if the dst is a memory range, then set the new author to be current Instruction node 'p_tempNode'
    if(bracketStr.size() > 0){
      int memSizeBytes = getMemSizeByte(dst,bracketStr);
      //remove the brackets from the string
      memAddrStr = bracketStr.substr(1, (bracketStr.size()-2));
      u_long hexValue = hexStrToLong(memAddrStr, p_tempNode, p_rootNode);

      #ifndef VAL_EQV
        set_dst_mem(memSizeBytes, hexValue, p_tempNode);
      #endif

      #ifdef VAL_EQV
      if(srcRegNumSize.first){
        #ifdef DEBUG_PRINT
          std::cout<< "(instrument_mov)srcReg and dstMem DETECTED!\n";
        #endif

          //if memDst already has the value of srcReg, then dont set the dst_mem author to p_tempNode and mark p_tempNode as extra.
          if (regAuthors == mapMemValue[(hexValue)]){
            p_tempNode->extra = 1;
          }

        if(!(regAuthors == mapMemValue[(hexValue)])){
           set_dst_mem(memSizeBytes, hexValue, p_tempNode);
           //if srcReg and dstMem, then get the last author of that source reg and associate it with the memory address dst.

             mapMemValue[(hexValue)] = regAuthors;

        }

      }
      #endif
    }
    else{
      //else if (dstRegNumSize.first) is equal to "null" then must be a constant like "17"
      //so create an OUTedge from the rootNode to the current tempInstruction node;
      //and create an INedge from the rootNode to the current tempInstruction node;
      set_dst_root(p_rootNode, p_tempNode);
    }
  }
}

int mark_ancestors (Node* p_tempNode){
  if ((p_tempNode->lineNum) == 0){
    return 1;
  }
  #ifdef DEBUG_PRINT
    std::cout<<"(mark_ancestors for node->lineNum: " << (p_tempNode->lineNum) << "\n";
  #endif
  if((p_tempNode-> extra) != 0){
    p_tempNode-> extra = 0;
    for (auto ut = std::begin((p_tempNode->inEdges)); ut != std::end((p_tempNode->inEdges)); ++ut)
    {
      mark_ancestors((*ut)->start);
    }
  }

  return 0;
}

void instrument_jump (Node* p_tempNode, uint32_t src_flags){
  set_src_flags(p_tempNode, src_flags);
  jumps.push_back(p_tempNode);
}

void instrument_call (Node* p_tempNode, uint32_t src_flags){
  calls.push_back(p_tempNode);
}

void instrument_instruction (std::string mnemonic, Node* p_tempNode, Node* p_rootNode, std::string wholeInstructionString)
{
  InstType instType = mapStringToInstType[mnemonic];

  std::string tempM = getMnemonic(oldInstruction);

  //do 'transitive immediate' optimization work here.
  #ifdef TRANS_IMME
    if ((tempM == "mov") && (mnemonic == "add")){
      #ifdef DEBUG_PRINT
      std::cout<< "[instrument_instruction]Current: " << wholeInstructionString << "\n";
      std::cout<< "[instrument_instruction]Prev: " << oldInstruction << "\n";
      #endif
      std::vector<std::string> oldinstrPieces;
      oldinstrPieces = getInstrPieces(oldInstruction);

      std::string oldmnemonic;
      oldmnemonic = oldinstrPieces.at(0);
      std::string olddst;
      olddst = oldinstrPieces.at(1);
      std::string oldsrc;
      oldsrc = oldinstrPieces.at(2);
      std::pair<int, int> oldsrcRegNumSize = checkForRegs(oldsrc);
      std::string oldbracketStr;
      std::string oldmemAddrStr;
      oldbracketStr = getStringWithinBrackets(oldsrc);

      std::vector<std::string> curinstrPieces;
      curinstrPieces = getInstrPieces(wholeInstructionString);

      std::string curmnemonic;
      curmnemonic = curinstrPieces.at(0);
      std::string curdst;
      curdst = curinstrPieces.at(1);
      std::string cursrc;
      cursrc = curinstrPieces.at(2);
      std::pair<int, int> cursrcRegNumSize = checkForRegs(cursrc);
      std::string curbracketStr;
      std::string curmemAddrStr;
      curbracketStr = getStringWithinBrackets(cursrc);

      switch (instType)
      {
        case InstType::add:
          #ifdef DEBUG_PRINT
          std::cout<< "[instrument_instruction]detected add: " << wholeInstructionString << "\n";
          #endif
          if (oldmnemonic == "mov"){
            #ifdef DEBUG_PRINT
            std::cout<< "[instrument_instruction]detected old Mov: " << oldInstruction << "\n";
            #endif
            if(oldsrcRegNumSize.first){
              //reg source for old mov, so do nothing
            }
            else{
              if(oldbracketStr.size() > 0){
                //memrange source for old mov, so do nothing
              }
              //if the old mov instruction had a IMMEDIATE value source, do optimization
              else{
                #ifdef DEBUG_PRINT
                std::cout<< "[instrument_instruction]detected IMME oldsrc: " << oldsrc << "\n";
                #endif
                if (cursrc == olddst){
                  #ifdef DEBUG_PRINT
                  std::cout<< "[instrument_instruction]detected cursrc is same as olddst: " << cursrc << ", " << olddst<< "\n";
                  #endif
                  std::string temp7 = "\"" + curmnemonic + " " + curdst + ", " + oldsrc + "\\n\"";
                  #ifdef DEBUG_PRINT
                  std::cout<< "[instrument_instruction]temp7: " << temp7 << "\n\n";
                  #endif
                  wholeInstructionString = temp7;
                }
              }
            }
          }
          break;
        default:
          break;
       }
    }
  #endif

  switch (instType)
  {
      case InstType::call:
          instrument_call(p_tempNode, 0);
           break;
      case InstType::jle:
      case InstType::jnle:
          instrument_jump(p_tempNode, ZF_FLAG|SF_FLAG|OF_FLAG);
           break;
      case InstType::jl:
      case InstType::jnl:
          instrument_jump(p_tempNode, SF_FLAG|OF_FLAG);
           break;
      case InstType::jz:
      case InstType::jne:
      case InstType::jnz:
          instrument_jump(p_tempNode, ZF_FLAG);
          break;
      case InstType::jns:
      case InstType::js:
          instrument_jump(p_tempNode, SF_FLAG);
          break;
      case InstType::jnbe:
      case InstType::jbe:
          instrument_jump(p_tempNode, CF_FLAG|ZF_FLAG);
           break;
      case InstType::jnb:
      case InstType::jb:
      case InstType::jae:
          instrument_jump(p_tempNode, CF_FLAG);
          break;
      case InstType::cmovbe:
      case InstType::cmovnbe:
          set_src_flags(p_tempNode, CF_FLAG|ZF_FLAG);
          instrument_mov(wholeInstructionString, 0, 0, p_tempNode, p_rootNode);
          break;
      case InstType::cmovz:
      case InstType::cmovnz:
          set_src_flags(p_tempNode, ZF_FLAG);
          instrument_mov(wholeInstructionString, 0, 0, p_tempNode, p_rootNode);
          break;
      case InstType::cmovb:
      case InstType::cmovnb:
          set_src_flags(p_tempNode, CF_FLAG);
          instrument_mov(wholeInstructionString, 0, 0, p_tempNode, p_rootNode);
          break;
      case InstType::cmovs:
      case InstType::cmovns:
          set_src_flags(p_tempNode, SF_FLAG);
          instrument_mov(wholeInstructionString, 0, 0, p_tempNode, p_rootNode);
          break;
      case InstType::cmovnle:
      case InstType::cmovle:
          set_src_flags(p_tempNode, ZF_FLAG|SF_FLAG|OF_FLAG);
          instrument_mov(wholeInstructionString, 0, 0, p_tempNode, p_rootNode);
          break;
      case InstType::cmovl:
      case InstType::cmovnl:
          set_src_flags(p_tempNode, SF_FLAG|OF_FLAG);
          instrument_mov(wholeInstructionString, 0, 0, p_tempNode, p_rootNode);
          break;
      case InstType::xchg:
          instrument_xchg(wholeInstructionString, 0, 0, p_tempNode, p_rootNode);
          break;
      case InstType::xadd:
          instrument_xchg(wholeInstructionString, 0, 0, p_tempNode, p_rootNode);
          instrument_addorsub(wholeInstructionString, SF_FLAG|ZF_FLAG|PF_FLAG|OF_FLAG|CF_FLAG|AF_FLAG, 0, p_tempNode, p_rootNode);
          break;
      //have to add a 'Z' character to these mnemonic enumerator values because 'and' 'or' 'xor' are reserved keywords in C
      case InstType::Zand:
      case InstType::Zor:
      case InstType::Zxor:
          instrument_addorsub(wholeInstructionString, SF_FLAG|ZF_FLAG|PF_FLAG, OF_FLAG|CF_FLAG|AF_FLAG, p_tempNode, p_rootNode);
          break;
      case InstType::pand:
      case InstType::por:
      case InstType::pxor:
          instrument_addorsub(wholeInstructionString, 0, 0, p_tempNode, p_rootNode);
          break;
      case InstType::add:
      case InstType::sub:
      case InstType::adc:
          instrument_addorsub(wholeInstructionString, SF_FLAG|ZF_FLAG|PF_FLAG|OF_FLAG|CF_FLAG|AF_FLAG, 0, p_tempNode, p_rootNode);
          break;
      case InstType::shl:
      case InstType::sar:
      case InstType::sal:
      case InstType::shr:
          instrument_addorsub(wholeInstructionString, CF_FLAG|OF_FLAG|SF_FLAG|ZF_FLAG|PF_FLAG|AF_FLAG, 0, p_tempNode, p_rootNode);
          break;
      case InstType::neg:
          instrument_neg_not(wholeInstructionString, CF_FLAG|OF_FLAG|SF_FLAG|ZF_FLAG|PF_FLAG|AF_FLAG, 0, p_tempNode, p_rootNode);
          break;
      case InstType::Znot:
          instrument_neg_not(wholeInstructionString, 0, 0, p_tempNode, p_rootNode);
          break;
      case InstType::mov:
      case InstType::movzx:
      case InstType::movsx:
      case InstType::movdqu:
      case InstType::pmovmskb:
      case InstType::pcmpeqb:
          instrument_mov(wholeInstructionString, 0, 0, p_tempNode, p_rootNode);
          break;
      case InstType::bsf:
          instrument_mov(wholeInstructionString, SF_FLAG|ZF_FLAG|PF_FLAG|OF_FLAG|CF_FLAG|AF_FLAG, 0, p_tempNode, p_rootNode);
          break;
      case InstType::div:
      case InstType::idiv:
          instrument_div(wholeInstructionString, SF_FLAG|ZF_FLAG|PF_FLAG|OF_FLAG|CF_FLAG|AF_FLAG, 0, p_tempNode, p_rootNode);
          break;
      case InstType::mul:
          instrument_mul(wholeInstructionString, CF_FLAG|OF_FLAG, SF_FLAG|ZF_FLAG|AF_FLAG|PF_FLAG, p_tempNode, p_rootNode);
          break;
      case InstType::imul:
          instrument_imul(wholeInstructionString, CF_FLAG|OF_FLAG, SF_FLAG|ZF_FLAG|AF_FLAG|PF_FLAG, p_tempNode, p_rootNode);
          break;
      case InstType::cmp:
      case InstType::test:
      case InstType::ptest:
          instrument_cmp_or_test(wholeInstructionString, CF_FLAG|OF_FLAG, SF_FLAG|ZF_FLAG|AF_FLAG|PF_FLAG, p_tempNode, p_rootNode);
          break;
      case InstType::setnz:
      case InstType::setz:
          set_src_flags(p_tempNode, ZF_FLAG);
          instrument_set(wholeInstructionString, 0, 0, p_tempNode, p_rootNode);
          break;
      case InstType::sets:
          set_src_flags(p_tempNode, SF_FLAG);
          instrument_set(wholeInstructionString, 0, 0, p_tempNode, p_rootNode);
          break;
      case InstType::setb:
          set_src_flags(p_tempNode, CF_FLAG);
          instrument_set(wholeInstructionString, 0, 0, p_tempNode, p_rootNode);
          break;
      case InstType::pushfd:
          set_src_regName("esp", p_tempNode);
          set_src_flags(p_tempNode, CF_FLAG|PF_FLAG|AF_FLAG|ZF_FLAG|SF_FLAG|OF_FLAG|DF_FLAG);
          set_dst_reg("esp", p_tempNode);
          break;
      case InstType::push:
      case InstType::pushw:
          instrument_push(wholeInstructionString, 0, 0, p_tempNode, p_rootNode);
          break;
      case InstType::popfd:
          set_src_regName("esp", p_tempNode);
          set_clear_flags(p_tempNode, CF_FLAG|PF_FLAG|AF_FLAG|ZF_FLAG|SF_FLAG|OF_FLAG|DF_FLAG, 0);
          set_dst_reg("esp", p_tempNode);
          break;
      case InstType::pop:
          instrument_pop(wholeInstructionString, 0, 0, p_tempNode, p_rootNode);
          break;
      case InstType::pcmpistri:
          instrument_pcmpistri(wholeInstructionString, CF_FLAG|PF_FLAG|AF_FLAG|ZF_FLAG|SF_FLAG|OF_FLAG, 0, p_tempNode, p_rootNode);
          break;
      case InstType::rep:
          instrument_rep_movsd(wholeInstructionString, 0, 0, p_tempNode, p_rootNode);
          break;
      case InstType::repne:
          instrument_repne_scasb(wholeInstructionString, CF_FLAG|PF_FLAG|AF_FLAG|ZF_FLAG|SF_FLAG|OF_FLAG, 0, p_tempNode, p_rootNode);
          break;
      case InstType::cld:
          set_clear_flags(p_tempNode, DF_FLAG, 0);
          break;
      case InstType::cwde:
          instrument_cwde(wholeInstructionString, 0, 0, p_tempNode, p_rootNode);
          break;
      case InstType::fld:
      case InstType::fxch:
      case InstType::fstp:
      case InstType::fild:
      case InstType::fmulp:
      case InstType::fistp:
          (p_tempNode->extra) = 0;
          break;
      case InstType::ret:
          set_src_regName("esp", p_tempNode);
          set_dst_reg("esp", p_tempNode);
          break;
      default:
          std::cout<< "[ERROR1]Unknown InstType mnemonic: " << mnemonic << "\n";
          //std::cout<< "[ERROR]Unknown InstType " << mapInstTypeToString[instType] << "\n";
  }
  //do 'transitive immediate' optimization work here.
  #ifdef TRANS_IMME
    oldInstruction = wholeInstructionString;
  #endif

  //6-22-18 this is bugged. doesnt print error when unknown inst type is encountered.
  if((mapStringToInstType.find(mnemonic)) == mapStringToInstType.end()){
    std::cout<< "[ERROR2]Unknown InstType mnemonic: " << mnemonic << "\n";
  }
  //this is bugged. doesnt print error when unknown inst type is encountered.
  /*
  if(mnemonic == "pmovmskb"){
    std::cout<< "[ERROR3]Unknown InstType mnemonic: " << mnemonic << (p_tempNode->lineNum) <<"\n";
  }
  */
}
  int main(int,char*[])
  {

    //...
    auto t1 = Clock::now();

    std::string filename("JUMPDexslice1.8151.c");
    //std::string filename("8151testslice50000.c");
    //std::string filename("3gccexslice1.2896.c");
    boost::iostreams::stream<boost::iostreams::file_source>file(filename.c_str());
    std::string line;
    int lineNum = 0;
    instrGraph* p_sliceGraph = new instrGraph();
    std::vector<std::string> instructionPieces;
    std::vector<std::string> tempPieces;
    Node* p_rootNode = new Node();
    Edge* ptempEdge = new Edge();
    p_rootNode->outEdges.push_back(ptempEdge);
    p_rootNode->outEdges[0]->start = p_rootNode;
    p_rootNode->inEdges.push_back(ptempEdge);
    p_rootNode->lineNum = 0;

    set_reg(0,1920,p_rootNode);
    set_clear_flags(p_rootNode, ALL_FLAGS, 0);

    #ifdef DEBUG_PRINT
      for (auto flagIt = std::begin(eflags_table); flagIt != std::end(eflags_table); ++flagIt){
        std::cout<<"eflags REGISTER authors: " << (*flagIt)->lineNum << "\n";
      }
    #endif

    std::cout<<"(main) Started processing exslice.c file: " << "\n";
    auto tb = Clock::now();
    std::cout << "Delta tb-t1: "
              << (std::chrono::duration_cast<std::chrono::nanoseconds>(tb - t1).count())/1000000000.0
              << " seconds" << std::endl;

    while (std::getline(file, line)) {
      lineNum++;
      #ifdef DEBUG_PRINT
        std::cout<< lineNum << "\n";
      #endif
      //Start reading actual slice instructions starting at line 5 (because the first 4 lines are padding that always need to be kept)
      if(lineNum >= 5){
        //this last line in exslice1.c is not really a slice instruction. Instead it is the last line of the exslice1.c file, );
        if(!(contains(line, ");"))){
          #ifdef DEBUG_PRINT
            std::cout<<"(main) line: "<<line << "\n";
          #endif
          if ((line.substr(1,2)).compare("b_") == 0)
            {

              line = line.substr(1,line.length());
              line = "\"call " + line;
              #ifdef DEBUG_PRINT
                std::cout<<"(main)3 line: "<<line << "\n";
              #endif
            }
          #ifdef DEBUG_PRINT
            std::cout<<"(main) line: "<<line << "\n";
          #endif
          std::string mnemonic = getMnemonic(line);
          //need to eventually delete this dynamically allocated memory
          Node* p_tempNode = new Node();

          #ifdef DEBUG_PRINT
            //std::cout<< p_tempNode->lineNum << "\n";
            std::cout<< line << "\n";
          #endif

          //setting the new instruction nodes' unique lineNum to its corresponding lineNum in the original exslice.c file.
          p_tempNode->lineNum = lineNum;

          instrument_instruction(mnemonic, p_tempNode, p_rootNode, line);

          //add the completed node with dst edges and src edges to the graph
          p_sliceGraph->nodes.push_back(p_tempNode);
        }
      }
    }

    //...
    file.close();

    std::cout<<"\n(main) Finished processing exslice.c file: " << "\n";
    auto ta = Clock::now();
    std::cout << "Delta ta-t1: "
              << std::chrono::duration_cast<std::chrono::nanoseconds>(ta - t1).count()/1000000000.0
              << " seconds" << std::endl;

    //get authors and mark them as EXTRA(removeable) or not extra (neccessary for the ouputs we care about)
    //int co = 0;
    for (auto shadowIt = std::begin(shadow_reg_table); shadowIt != std::end(shadow_reg_table); ++shadowIt){
      if (((*shadowIt)->lineNum) != 0){
        outputNodes.insert((*shadowIt));
        //mark_ancestors((*shadowIt));
        //std::cout<<"shadow_reg_table REGISTER authors: " << co << ", "  << (*shadowIt)->lineNum << "\n";
        //co++;
      }
    }

    for (auto flagIt = std::begin(eflags_table); flagIt != std::end(eflags_table); ++flagIt){
      outputNodes.insert((*flagIt));
      //mark_ancestors((*flagIt));
      //std::cout<<"eflags REGISTER authors: " << (*flagIt)->lineNum << "\n";
    }

    for (auto jumpIt = std::begin(jumps); jumpIt != std::end(jumps); ++jumpIt){
      outputNodes.insert((*jumpIt));
      //mark_ancestors((*flagIt));
      //std::cout<<"jump's ancestors marked. jump at line: " << (*flagIt)->lineNum << "\n";
    }

    for (auto callIt = std::begin(calls); callIt != std::end(calls); ++callIt){
      outputNodes.insert((*callIt));
      //mark_ancestors((*flagIt));
      //std::cout<<"calls's ancestors marked. call at line: " << (*flagIt)->lineNum << "\n";
    }

    for (auto const& x : mapMem)
    {
      outputNodes.insert((x.second));
      //mark_ancestors(x.second);
      //std::cout<<"memory's ancestors marked. memory at : " << x.first << " written to by line " <<(x.second)->lineNum<< "\n";
    }

    //bfs marking all ancestors of outputNodes
    std::list <Node *> queue;

    for (auto const& outputN : outputNodes)
    {
      outputN->visited = 1;
      queue.push_back(outputN);

      std::list<Node *>::iterator iterq;
      while(!queue.empty()){
        Node * vNode = queue.front();
        #ifdef DEBUG_PRINT
        std::cout << vNode->lineNum << " visited. \n";
        #endif
        queue.pop_front();

        for (auto edgeIt2 = std::begin((vNode)->inEdges); edgeIt2 != std::end((vNode)->inEdges); ++edgeIt2){
          #ifdef DEBUG_PRINT
          std::cout << vNode->lineNum << " inEdge is " << ((*edgeIt2)->start)->lineNum << "\n";
          #endif
          if(((*edgeIt2)->start)->visited == 0){
            ((*edgeIt2)->start)->visited = 1;
            queue.push_back(((*edgeIt2)->start));
          }
        }
      }
    }

    int allNodeCount = 0;
    int extraNodeCount = 0;
    for (auto const& allNode : (p_sliceGraph->nodes))
    {
      #ifdef DEBUG_PRINT
      std::cout<<"allNode: lineNum, visited " << allNode->lineNum << ", " << allNode->visited << "\n";
      #endif
      if((allNode->visited) == 0){
        extraNodes.push_back(allNode);
        extraNodeCount++;
      }
    }

    for (auto it = std::begin(p_sliceGraph->nodes); it != std::end(p_sliceGraph->nodes); ++it){
      allNodeCount++;

      #ifdef DEBUG_PRINT
        std::cout<< ((*it)->lineNum) << " ,extra is: " << ((*it)->extra) <<"\n";
        for (auto ut = std::begin(((*it)->inEdges)); ut != std::end(((*it)->inEdges)); ++ut){
          std::cout <<" inEdges: "<<((*ut)->start)->lineNum << "->" << ((*ut)->finish)->lineNum << " ";
        }
        std::cout<<"\n";
        for (auto kt = std::begin(((*it)->outEdges)); kt != std::end(((*it)->outEdges)); ++kt){
          std::cout<< " outEdges: "<<((*kt)->start)->lineNum << "->" << ((*kt)->finish)->lineNum << " ";
        }
        std::cout<<"\n";
      #endif
    }

    #ifdef DEBUG_PRINT
      for (auto const& extras : extraNodes)
      {
        std::cout<<"Extra Node at line : " << extras->lineNum << "\n";
      }
    #endif

    std::cout<<"\nOriginal Instruction Count is : " << allNodeCount << "\n";
    std::cout<<"Extra Instruction Count is : " << extraNodeCount << "\n";

    std::cout<<"\n(main) Finished doing backwards-pass over Graph.: " << "\n";
    auto t2 = Clock::now();
    std::cout << "Delta t2-t1: "
              << std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count()/1000000000.0
              << " seconds" << std::endl;
    //...
    std::remove("optInfo.txt"); //delete old outfile1, optInfo.txt to make room for new one.

    std::ofstream outfile1;
    outfile1.open ("optInfo.txt");

    if (outfile1.is_open()){
      outfile1<<"Original filename is: " << filename << "\n";
      outfile1<<"\nOriginal Instruction Count is : " << allNodeCount << "\n";
      outfile1<<"Extra Instruction Count is : " << extraNodeCount << "\n\n" << "====" << "\n";
      for (auto const& extra1 : extraNodes)
      {
        outfile1<<"Extra Node at line : " << extra1->lineNum << ", node->extra is:" << extra1->extra << "\n";
      }
      outfile1.close();
    }
    else{
        std::cout<< "[ERROR] Unable to open outfile1, optInfo.txt.";
    }

    //...Delete mem operations here
    delete p_rootNode;
    delete ptempEdge;
    //iterate through each node in the slice Graph
    //for each node, iterate through its inEdges and outEdges and delete each edge pointer
    //then finally delete every node in the slice Graph
    for (auto it = std::begin(p_sliceGraph->nodes); it != std::end(p_sliceGraph->nodes); ++it){
      for (auto edgeIt2 = std::begin((*it)->inEdges); edgeIt2 != std::end((*it)->inEdges); ++edgeIt2){
        delete (*edgeIt2);
      }
      for (auto edgeIt3 = std::begin((*it)->outEdges); edgeIt3 != std::end((*it)->outEdges); ++edgeIt3){
        delete (*edgeIt3);
      }
    }
    for (auto nodeIt = std::begin(p_sliceGraph->nodes); nodeIt != std::end(p_sliceGraph->nodes); ++nodeIt){
      delete (*nodeIt);
    }
    delete p_sliceGraph;

    /* 6-25-18 come back to this boost graph lib work

    // create a typedef for the Graph type
    typedef adjacency_list<setS, vecS, bidirectionalS> digraph;

    // Make convenient labels for the vertices
    enum { A, B, C, D, E, N };
    const int num_vertices = N;
    const char* name = "ABCDE";

    // writing out the edges in the graph
    typedef std::pair<int, int> Edge;
    Edge edge_array[] =
    { Edge(A,B), Edge(A,D), Edge(C,A), Edge(D,C),
      Edge(C,E), Edge(B,D), Edge(D,E) };
    const int num_edges = sizeof(edge_array)/sizeof(edge_array[0]);

    // declare a graph object
    digraph g(num_vertices);

    //...
    add_edge(0,4, g);
    //...

    // add the edges to the graph object
    for (int i = 0; i < num_edges; ++i)
      add_edge(edge_array[i].first, edge_array[i].second, g);

    //...

    typedef graph_traits<digraph>::vertex_descriptor Vertex;

    // get the property map for vertex indices
    typedef property_map<digraph, vertex_index_t>::type IndexMap;
    IndexMap index = get(vertex_index, g);

    std::cout << "vertices(g) = ";
    typedef graph_traits<digraph>::vertex_iterator vertex_iter;
    std::pair<vertex_iter, vertex_iter> vp;
    for (vp = vertices(g); vp.first != vp.second; ++vp.first) {
      Vertex v = *vp.first;
      std::cout << index[v] <<  " ";
    }
    std::cout << std::endl;

    // ...
    std::cout << "edges(g) = ";
    graph_traits<digraph>::edge_iterator ei, ei_end;
    for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
        std::cout << "(" << index[source(*ei, g)]
                  << "," << index[target(*ei, g)] << ") ";
    std::cout << std::endl;

    // ...
     write_graphviz(std::cout, g);

    */

    //...
    return 0;
  }


text:
/*
 * TimeInterpolator.cpp
 *
 *  Created on: Aug 24, 2012
 *      Author: dberrios
 */

#include "TimeInterpolator.h"
#include "GeneralFileReader.h"
#include "FileReader.h"
#include "Interpolator.h"
#include "Utils.h"
#include "Kameleon.h"
#include "CCMCTime.h"
#include "string.h"
#include <algorithm>
#include <boost/functional/hash.hpp>

using namespace ccmc;
namespace boost
{

//	bool operator==(const boost::posix_time::ptime& a, const boost::posix_time::ptime& b)
//	{
//		  if (a.date() == b.date() && a.time_of_day() == b.time_of_day())
//			  return true;
//		  else
//			  return false;
//	}
}

namespace ccmc
{
	TimeInterpolator::TimeInterpolator()
	{
		// TODO Auto-generated constructor stub
		isSorted = false;

	}

	TimeInterpolator::~TimeInterpolator()
	{
		// TODO Auto-generated destructor stub
	}

	void TimeInterpolator::addTimestep(const std::string& filename)
	{
		ccmc::Kameleon * kameleon = new Kameleon();
		int status = kameleon->open(filename);
		if (status == ccmc::FileReader::OK)
		{
			Time time = kameleon->getCurrentTime();
			this->timesteps.push_back(time);
			std::sort(timesteps.begin(), timesteps.end());
			//std::reverse(timesteps.begin(), timesteps.end());
			this->current_kameleon_files[time] = kameleon;
			this->current_kameleon_interpolators[time] = kameleon->createNewInterpolator();
		}
		std::cout << "array: " << std::endl;
		for (int i = 0; i < this->timesteps.size(); i++)
		{
			std::cout << "time[" << i << "]: " << timesteps[i] << std::endl;
		}

	}

	void TimeInterpolator::removeTimestep(const Time& time)
	{
		this->current_kameleon_files.erase(time);
		this->current_kameleon_interpolators.erase(time);
	}

	std::vector<Time> TimeInterpolator::getTimesteps()
	{
		// std::vector<Time> timesteps;
		return this->timesteps;
	}

	/**
	 * Manages the variables loaded into memory.
	 * @variable variables The vector of variables
	 */
	void TimeInterpolator::manageVariables(
			const std::vector<std::string>& variables, Kameleon* a) {
		std::vector<std::string> loadedVariables = a->getLoadedVariables();
		//unload any unnecessary variables
		for (int i = 0; i < loadedVariables.size(); i++) {
			if (std::find(variables.begin(), variables.end(), loadedVariables[i])
					== variables.end()) {
				a->unloadVariable(loadedVariables[i]);
			}
		}
		for (int i = 0; i < variables.size(); i++) {
			std::cout << "loading variable " << variables[i] << std::endl;
			a->loadVariable(variables[i]);
		}
	}

	/**
	 * Manages the variables loaded into memory.
	 * @variable variables The vector of variables
	 */
	void TimeInterpolator::manageVariables(
			const char * variables[], int numVars, Kameleon* a) {
		std::vector<std::string> loadedVariables = a->getLoadedVariables();
		//unload any unnecessary variables
		for (int i = 0; i < loadedVariables.size(); i++) {
			int count = 0;
			for (int j = 0; j < numVars; j++)
			{
				if (loadedVariables[i] != variables[j])
					count ++;

			}
			if (count == numVars)
				a->unloadVariable(loadedVariables[i]);
		}
		for (int i = 0; i < numVars; i++) {
			std::cout << "loading variable " << variables[i] << std::endl;
			a->loadVariable(variables[i]);
		}
	}

	/**
	 * Manages the memory and the opened files based on the time and variable specified.
	 */
	bool TimeInterpolator::manageMemory(const Time& time, const std::vector<std::string>& variables)
	{
		std::cout << "time: " << time.toString() << ": " << time.getEpoch() << std::endl;
		std::cout << "timesteps: " << TimeInterpolator::toString(timesteps[0]) << ": " << timesteps[0].getEpoch();
		std::cout << " " << TimeInterpolator::toString(timesteps[1]) << ": " << timesteps[1].getEpoch() << std::endl;
		int index = Utils<Time>::binary_search(this->timesteps, 0, this->timesteps.size(), time);
		std::cout << "manageMemory. index: " << index << std::endl;
		//found the timestep(s)
		if (index >-1)
		{

			//if it is an exact time match and the file is already one of the current_kameleon_files, load just one file
			if (this->timesteps[index] == time && this->current_kameleon_files.find(this->timesteps[index]) != this->current_kameleon_files.end())
			{
				//just load in one file
				Kameleon * found = this->current_kameleon_files[time];
				manageVariables(variables, found);

			}
			//the timesteps are both within the list
			else if (index + 1 < this->timesteps.size() &&
					this->current_kameleon_files.find(this->timesteps[index]) != this->current_kameleon_files.end() &&
					this->current_kameleon_files.find(this->timesteps[index+1]) != this->current_kameleon_files.end())
			{
				//load the variables in the files
				Kameleon * before = this->current_kameleon_files[this->timesteps[index]];
				Kameleon * after = this->current_kameleon_files[this->timesteps[index+1]];

				manageVariables(variables, before);
				manageVariables(variables, after);
			}
//			else
//			{
//				//this->current_kameleon_files.clear();
//				Kameleon * kameleon = new Kameleon();
//				//kameleon->open(this->timesteps_map[this->timesteps[index]]);
//				kameleon->loadVariable(variable);
//			}
			return true;
		} else
		{
			//this->current_kameleon_files.clear();
			//do nothing
			std::cout << "index was not > -1. returning" << std::endl;
			return false;
		}
	}

	/**
		 * Manages the memory and the opened files based on the time and variable specified.
		 */
		bool TimeInterpolator::manageMemory(const Time& time, const char * variables[], int numVars)
		{

			std::cout << "time: " << time.toString() << " timesteps: " << TimeInterpolator::toString(timesteps[0]) << " " << TimeInterpolator::toString(timesteps[1]) << std::endl;
			int index = Utils<Time>::binary_search(this->timesteps, 0, this->timesteps.size(), time);

			//found the timestep(s)
			if (index >-1)
			{

				//if it is an exact time match and the file is already one of the current_kameleon_files, load just one file
				if (this->timesteps[index] == time && this->current_kameleon_files.find(this->timesteps[index]) != this->current_kameleon_files.end())
				{
					//just load in one file
					Kameleon * found = this->current_kameleon_files[time];
					manageVariables(variables, numVars, found);

				}
				//the timesteps are both within the list
				else if (index + 1 < this->timesteps.size() &&
						this->current_kameleon_files.find(this->timesteps[index]) != this->current_kameleon_files.end() &&
						this->current_kameleon_files.find(this->timesteps[index+1]) != this->current_kameleon_files.end())
				{
					//load the variables in the files
					Kameleon * before = this->current_kameleon_files[this->timesteps[index]];
					Kameleon * after = this->current_kameleon_files[this->timesteps[index+1]];

					manageVariables(variables, numVars, before);
					manageVariables(variables, numVars, after);
				}
	//			else
	//			{
	//				//this->current_kameleon_files.clear();
	//				Kameleon * kameleon = new Kameleon();
	//				//kameleon->open(this->timesteps_map[this->timesteps[index]]);
	//				kameleon->loadVariable(variable);
	//			}
				return true;
			} else
			{
				//this->current_kameleon_files.clear();
				//do nothing
				std::cout << "index was not > -1. returning" << std::endl;
				return false;
			}
		}

	Kameleon * TimeInterpolator::getKameleon(const Time& time)
	{
		int index = Utils<Time>::binary_search(this->timesteps, 0, this->timesteps.size(), time);
		if (index > -1) //time within range; if t in [t0, t1], then t = t0, t1, or t > t0
		{
			std::cout <<"Time for Kameleon object is within range of available timesteps"<<std::endl;
			if (current_kameleon_files.find(this->timesteps[index]) != this->current_kameleon_files.end())
			{
				std::cout<<"returning kameleon object for time: "<< timesteps[index].toString()<<std::endl;
				return this->current_kameleon_files[timesteps[index]];
			} else //set the interpolator
			{
				std::cout<<"No kameleon object available, returning NULL"<<std::endl;
				return NULL;
			}
		} else
		{
			std::cout << "Time for requested kameleon object is out of range of loaded timesteps, returning NULL." << std::endl;
			return NULL;
		}

	}

	Interpolator * TimeInterpolator::getInterpolator(const Time& time)
	{
		int index = Utils<Time>::binary_search(this->timesteps, 0, this->timesteps.size(), time);
		Interpolator * a;
		if (index > -1) //time within range; if t in [t0, t1], then t = t0, t1, or t > t0
		{
			std::cout <<"Time for interpolator is within range of available timesteps"<<std::endl;
			//check that interpolator is loaded
			if (current_kameleon_interpolators.find(this->timesteps[index]) != this->current_kameleon_interpolators.end())
			{
				std::cout<<"Interpolator already loaded" <<std::endl;
				a = this->current_kameleon_interpolators[timesteps[index]];
			} else //set the interpolator
			{
				std::cout<<"Interpolator not loaded, creating new one and adding to map"<<std::endl;
				a = this->current_kameleon_files[timesteps[index]]->createNewInterpolator();
				this-> current_kameleon_interpolators[timesteps[index]] = a;
			}
			std::cout<<"returning interpolator for time: "<< timesteps[index].toString()<<std::endl;
			return a;
		} else
		{
			std::cout << "Time for requested interpolator is out of range of loaded timesteps, returning NULL." << std::endl;
			return NULL;
		}
	}

	float TimeInterpolator::interpolate(const Time& time, const std::string& variable, const float& c0, const float& c1, const float& c2)
	{
		int index = Utils<Time>::binary_search(this->timesteps, 0, this->timesteps.size(), time);
		Interpolator * a;
		if (index > -1) //time is within range of loaded timesteps
		{
			//replace with call to getInterpolator

			if (time == this->timesteps[index])
			{
				//check that interpolator is loaded
				if (current_kameleon_interpolators.find(this->timesteps[index]) != this->current_kameleon_interpolators.end())
				{
					a = this->current_kameleon_interpolators[time];
				} else //set the interpolator
				{
					a = this->current_kameleon_files[time]->createNewInterpolator();
					this-> current_kameleon_interpolators[time] = a;
				}

				float value = a->interpolate(variable, c0, c1, c2);
				// delete a; //when to delete this? prolly not here
				return value;
			} else
			{
				Interpolator * b;
				Time atime = this->timesteps[index];
				Time btime = this->timesteps[index+1];
				//Need to check if interpolators for atime and btime are loaded
				if (current_kameleon_interpolators.find(atime) != this->current_kameleon_interpolators.end())
				{
					a = this->current_kameleon_interpolators[atime];
				} else //store the interpolator
				{
					a = this->current_kameleon_files[atime]->createNewInterpolator();
					this-> current_kameleon_interpolators[atime] = a;
				}
				if (current_kameleon_interpolators.find(btime) != this->current_kameleon_interpolators.end())
				{
					b = this->current_kameleon_interpolators[btime];
				} else //store the interpolator
				{
					b = this->current_kameleon_files[btime]->createNewInterpolator();
					this-> current_kameleon_interpolators[btime] = b;
				}

				// Interpolator * a = this->current_kameleon_files[atime]->createNewInterpolator(); //not deallocated!
				// Interpolator * b = this->current_kameleon_files[btime]->createNewInterpolator();
				double duration = btime-atime;
				double deltatime = (time - atime);

				double r = deltatime / duration;
				float avalue = a->interpolate(variable, c0, c1, c2);
				float bvalue = b->interpolate(variable, c0, c1, c2);

				float deltaValue = bvalue - avalue;
				float value = avalue + deltaValue * r;
				// std::cout << "inside. interpolated value: " << value << std::endl;
				return value;
			}
		} else
			return
				-1.f;
	}

	float TimeInterpolator::interpolate(const Time& time, int variable, const float& c0, const float& c1, const float& c2)
	{
		int index = Utils<Time>::binary_search(this->timesteps, 0, this->timesteps.size(), time);
		Interpolator * a;
		if (index > -1)
		{
			if (time == this->timesteps[index])
			{
				//check that interpolator is loaded
				if (current_kameleon_interpolators.find(this->timesteps[index]) != this->current_kameleon_interpolators.end())
				{
					a = this->current_kameleon_interpolators[time];
				} else //set the interpolator
				{
					a = this->current_kameleon_files[time]->createNewInterpolator();
					this-> current_kameleon_interpolators[time] = a;
				}

				float value = a->interpolate(variable, c0, c1, c2);
				return value;

			} else
			{
				Interpolator * b;
				Time atime = this->timesteps[index];
				Time btime = this->timesteps[index+1];
				//Need to check if interpolators for atime and btime are loaded
				if (current_kameleon_interpolators.find(atime) != this->current_kameleon_interpolators.end())
				{
					a = this->current_kameleon_interpolators[atime];
				} else //store the interpolator
				{
					a = this->current_kameleon_files[atime]->createNewInterpolator();
					this-> current_kameleon_interpolators[atime] = a;
				}
				if (current_kameleon_interpolators.find(btime) != this->current_kameleon_interpolators.end())
				{
					b = this->current_kameleon_interpolators[btime];
				} else //store the interpolator
				{
					b = this->current_kameleon_files[btime]->createNewInterpolator();
					this-> current_kameleon_interpolators[btime] = b;
				}

				// Interpolator * a = this->current_kameleon_files[atime]->createNewInterpolator(); //wasn't deallocated!
				// Interpolator * b = this->current_kameleon_files[btime]->createNewInterpolator();
				double duration = btime-atime;
				double deltatime = (time - atime);

				double r = deltatime / duration;
				float avalue = a->interpolate(variable, c0, c1, c2);
				float bvalue = b->interpolate(variable, c0, c1, c2);

				float deltaValue = bvalue - avalue;
				float value = avalue + deltaValue * r;
				// std::cout << "inside. interpolated value: " << value << std::endl;
				return value;
			}
		} else
			return
				-1.f;
	}

	void TimeInterpolator::clearAll()
	{

		this->timesteps_map.clear();
		this->timesteps.clear();
		this->current_kameleon_files.clear();
		this->current_kameleon_interpolators.clear();

	}

	inline std::size_t hash_value(Time const& time)
	{
	  std::size_t seed = 0;
	  boost::hash_combine(seed, time.getYear());
	  boost::hash_combine(seed, time.getMonth());
	  boost::hash_combine(seed, time.getDay());
	  boost::hash_combine(seed, time.getHour());
	  boost::hash_combine(seed, time.getMinute());
	  boost::hash_combine(seed, time.getSeconds());
	  boost::hash_combine(seed, time.getMilliseconds());
	  //boost::hash_combine(seed, tod.hours());
	  //boost::hash_combine(seed, tod.minutes());
	  //boost::hash_combine(seed, tod.seconds());
	  //boost::hash_combine(seed, tod.fractional_seconds());
	  return seed;
	}

	Time TimeInterpolator::parseTime(const std::string& timeString)
	{
		std::cout << "timeString inside parseTime: " << timeString << std::endl;
		std::cout << "before declaring string" << std::endl;
		char timeString_c_str[EPOCH3_STRING_LEN+1];
		std::cout << "before string copy" << std::endl;
		strncpy(timeString_c_str, (char *)timeString.c_str(), EPOCH_STRING_LEN);
		std::cout << "after string copy" << std::endl;
		timeString_c_str[4] = '-';
		timeString_c_str[7] = '-';
		std::cout << "before creating epoch time with parseEPOCH3" << std::endl;
		double epoch = parseEPOCH3(timeString_c_str);
		std::cout << "epoch value in parseTime: " << epoch << std::endl;
		long year, month, day, hour, minute, second, msec;
		year = month = day = hour = minute = second = msec = 1;
		EPOCHbreakdown(epoch, &year, &month, &day, &hour, &minute, &second, &msec);
		Time time;
		time.setYear((short)year);
		time.setMonth((short)month);
		time.setDay((short)day);
		time.setHour((short)hour);
		time.setMinute((short)minute);
		time.setSeconds((short)second);
		time.setMilliseconds((short)msec);
		return time;

	}

	std::string TimeInterpolator::toString(const Time& time)
	{
		char epochString[EPOCH3_STRING_LEN+1];
		std::cout << "time: " << time.toString() << " " << time.getEpoch() << std::endl;
		encodeEPOCH3(time.getEpoch(), epochString);
		return epochString;
	}

	void TimeInterpolator::closeAndCleanupMemory()
	{

		for (int i = 0; i < this->timesteps.size(); i++)
		{
			this->current_kameleon_files[timesteps[i]]->close();
		}
		this->timesteps.clear();
		this->current_kameleon_files.clear();
		this->current_kameleon_interpolators.clear();
	}

};

ext: cpp

max_stars_repo_name: alexanderbock/Kameleon-Converter

max_issues_repo_name: alexanderbock/Kameleon-Converter

max_forks_repo_name: alexanderbock/Kameleon-Converter


text:
/*=============================================================================
    Copyright (c) 2010 Christopher Schmidt

    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/

#ifndef BOOST_FUSION_ADAPTED_ADT_ADAPT_ASSOC_ADT_NAMED_HPP
#define BOOST_FUSION_ADAPTED_ADT_ADAPT_ASSOC_ADT_NAMED_HPP

#include <boost/fusion/adapted/adt/adapt_assoc_adt.hpp>
#include <boost/fusion/adapted/struct/detail/proxy_type.hpp>
#include <boost/fusion/support/config.hpp>

#define BOOST_FUSION_ADAPT_ASSOC_ADT_NAMED_NS(WRAPPED_TYPE, NAMESPACE_SEQ,     \
                                              NAME, ATTRIBUTES)                \
                                                                               \
  BOOST_FUSION_ADAPT_STRUCT_DEFINE_PROXY_TYPE_IMPL(WRAPPED_TYPE,               \
                                                   (0)NAMESPACE_SEQ, NAME)     \
                                                                               \
  BOOST_FUSION_ADAPT_ASSOC_ADT_AS_VIEW(                                        \
      BOOST_FUSION_ADAPT_STRUCT_NAMESPACE_DECLARATION((0)NAMESPACE_SEQ) NAME,  \
      ATTRIBUTES)

#define BOOST_FUSION_ADAPT_ASSOC_ADT_NAMED(WRAPPED_TYPE, NAME, ATTRIBUTES)     \
  BOOST_FUSION_ADAPT_ASSOC_ADT_NAMED_NS(                                       \
      WRAPPED_TYPE, (boost)(fusion)(adapted), NAME, ATTRIBUTES)

#endif

ext: hpp

max_stars_repo_name: henrywarhurst/matrix

max_issues_repo_name: henrywarhurst/matrix

max_forks_repo_name: henrywarhurst/matrix


text: #include <boost/numeric/odeint/iterator/integrate/integrate_n_steps.hpp>

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
/**
 * Copyright (c) 2018, University Osnabrück
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the University Osnabrück nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL University Osnabrück BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __DIRECTORY_PARSER_HPP__
#define __DIRECTORY_PARSER_HPP__

#include <string>
#include <vector>

#include <boost/filesystem.hpp>
#include <Eigen/Dense>

#include "lvr2/io/Timestamp.hpp"
#include "lvr2/io/PointBuffer.hpp"
#include "lvr2/types/MatrixTypes.hpp"
#include "lvr2/registration/TransformUtils.hpp"

namespace lvr2
{

struct ScanInfo
{
    string              m_filename;
    size_t              m_numPoints;
    Transformd          m_pose;
};

class ScanDirectoryParser
{

public:
    ScanDirectoryParser(const std::string& directory) noexcept;

    void setPointCloudPrefix(const std::string& prefix);
    void setPointCloudExtension(const std::string& extension);
    void setPosePrefix(const std::string& prefix);
    void setPoseExtension(const std::string& extension);

    void setStart(int s);
    void setEnd(int e);

    void parseDirectory();

    PointBufferPtr randomSubSample(const size_t& targetSize);
    PointBufferPtr octreeSubSample(const double& voxelSize, const size_t& minPoints = 5);

    ~ScanDirectoryParser();

private:

    using Path = boost::filesystem::path;

    size_t examinePLY(const std::string& filename);
    size_t examineASCII(const std::string& filename);

    size_t                  m_numPoints;
    std::string             m_pointPrefix;
    std::string             m_posePrefix;
    std::string             m_poseExtension;
    std::string             m_pointExtension;
    std::string             m_directory;

    size_t                  m_start;
    size_t                  m_end;

    std::vector<ScanInfo*>   m_scans;
};

} // namespace lvr2

#endif

max_stars_repo_name: uos/lvr

max_issues_repo_name: uos/lvr

max_forks_repo_name: uos/lvr