<commit_before>/* FILE INFORMATION
File:     apex.cpp
Authors:  Matthew Cole <mcole8@binghamton.edu>
          Brian Gracin <bgracin1@binghamton.edu>
Description: Contains helper functions controlling simulator high-level behavior.
*/
#include <iostream>
#include "code.h"
#include "cpu.h"
#include "data.h"
#include "register.h"
#include "rob.h"
#include "iq.h"
#include "apex.h"

#define DEBUG 1

// Initialize simulator state and stats variables with external linkage
int cycle = 0;
int pc = 4000;
int dispatched = 0;
int no_dispatch = 0;
int issued = 0;
int no_issued = 0;
int committed = 0;
int committed_load = 0;
int committed_store = 0;
int no_commit= 0;

// Initialize simulator flags
int Z = 0;
int Zcycle = 0;

//Display an interface help message
void help()
{
  std::cout << "| Command        | Action\n"
            << "|----------------|---------------------------------------------\n"
            << "| i              |Initialize the simulator state\n"
            << "| s <n>          |Simulate <n> number of cycles\n"
            << "| dall           |Display the full simulator internal state\n"
            << "| dcpu           |Display CPU stage contents\n"
            << "| diq            |Display Issue Queue entries and status\n"
            << "| dmap           |Display Front-end, Back-end Register Tables\n"
            << "| dmem <a1> <a2> |Display memory from address <a1> to <a2>\n"
            << "| drob           |Display ROB contents\n"
            << "| dstats         |Display Stats\n"
            << "| durf           |Display Unified Register File\n"
            << "| urf <n>        |Set URF Size to <n> physical registers\n"
            << "| q              |Quit the simulator\n"
            << "| h              |Display this help message" << std::endl;
}

// Initialize the simulator to a known state.
void initialize(CPU &mycpu, Registers &myregisters, Data &mydata, ROB &myrob, IQ &myiq)
{
  if (VERBOSE >= 1)
    std::cout << "Initializing ... " << std::endl;

  //Reset simulator state and stats variables
  cycle = 0;
  pc = 4000;
  dispatched = 0;
  no_dispatch = 0;
  issued = 0;
  no_issued = 0;
  committed = 0;
  committed_load = 0;
  committed_store = 0;

  //Initialize each of the instances by delegating to member functions
  mycpu.initialize();
  myregisters.initialize();
  mydata.initialize();
} //end initialize()

// Display the simulator internal state.
void display(CPU &mycpu, Registers &myregisters, Data &mydata, ROB &myrob, IQ &myiq,
  std::string mod, int a1, int a2)
{
  //Sanitize inputs
  if  (mod != "all" &&
        mod != "cpu" &&
        mod != "iq"  &&
        mod != "map" &&
        mod != "mem" &&
        mod != "rob" &&
        mod != "stats" &&
        mod != "urf"){
            std::cerr << "Display modifier " << mod << " not understood.";
            mod = "";
  }
  if ((mod == "all" || mod == "mem") && a1 < 0){
    std::cerr << "Memory range start is out of bounds. Setting to 0." << std::endl;
    a1 = 0;
  }
  if ((mod == "all" || mod == "mem") && a2 > 3996){
    std::cerr << "Memory range stop is out of bounds. Setting to 3996." << std::endl;
    a2 = 3996;
  }
  if ((mod == "all" || mod == "mem") && (a1 > a2)){
    //We assert a1 <= a2. Swap a1, a2 if assertion is false.
    a1 = a1 ^ a2;
    a2 = a1 ^ a2;
    a1 = a1 ^ a2;
  }

  if (VERBOSE >= 1)
    std::cout << "Displaying simulator state ... " << std::endl;

  //Print simulator state variables
  std::cout << "cycle: " << cycle << " pc: " << pc << std::endl;

  //Display each of the instances by delegating to member functions
  if (mod == "all" || mod == "cpu"){
    if (VERBOSE >= 1)
      std::cout << "-----------\n" << "CPU\n" << "-----------\n";
    mycpu.display();
  }
  if (mod == "all" || mod == "iq"){
    if (VERBOSE >= 1)
      std::cout << "-----------\n" << "Issue Queue\n" << "-----------\n";
    myiq.display();
  }
  if (mod == "all" || mod == "map"){
    if (VERBOSE >= 1)
      std::cout << "-----------\n" << "Rename Tables\n" << "-----------\n";
    myregisters.dMap();
  }
  if (mod == "all" || mod == "mem"){
    if (VERBOSE >= 1)
      std::cout << "-----------\n" << "Data Memory\n" << "-----------\n";
    mydata.display(a1, a2);
  }
  if (mod == "all" || mod == "rob"){
    if (VERBOSE >= 1)
      std::cout << "-----------\n" << "Reorder Buffer\n" << "-----------\n";
    myrob.display();
  }
  if (mod == "all" || mod == "stats"){
    if (VERBOSE >= 1)
      std::cout << "-----------\n" << "Statistics\n" << "-----------\n";
    stats();
  }
  if (mod == "all" || mod == "urf"){
    if (VERBOSE >= 1)
      std::cout << "-----------\n" << "Registers\n" << "-----------\n";
    myregisters.dUrf();
  }
} // end display()

//Display simulator stats
void stats()
{
  std::cout << "-----------\n" << "Statistics\n" << "-----------\n";
  std::cout << "Cycle: " << cycle << std::endl;
  std::cout << "Instructions through:\n"
            << " Dispatch=" << dispatched
            << " Issue=" << issued
            << " Commit=" << committed << std::endl;

  std::cout << "IPC: " << ((double) committed) / (double) cycle << std::endl;
  std::cout << "# cycles dispatch stalled: " << no_dispatch << std::endl;
  std::cout << "# cycles with no issue: " << no_issued << std::endl;
  std::cout << "# LOAD instructions committed: " << committed_load << std::endl;
  std::cout << "# STORE instructions committed: " << committed_store << std::endl;
  std::cout << "# cycles with no commit: " << no_commit << std::endl;
}

// Simulate the operation of the system for <num_cycles>, or until a HALT
//instruction is encountered, or until an error occurs in simulation.
//Return the current cycle number after simulation pauses or halts.
int simulate(int num_cycles, CPU &mycpu, Code &mycode, Registers &myregisters,
  Data &mydata, ROB &myrob, IQ &myiq)
{
  int start = ::cycle;
  int stop = ::cycle + num_cycles;

  for (int c = start; c < stop; c++)
  {
    //Perform one cycle of simulation
    if (VERBOSE >= 1)
      std::cout << "Simulating cycle " << cycle << " ..." << std::endl;

    #if (DEBUG)
      mycpu.display();
      //myregisters.dMap();
      //myregisters.dUrf();
      mydata.display(0, 100);
    #endif

    //cpu::simulate() returns 0 if execution should not continue
    //(EOF, HALT or exception encountered)
    if(mycpu.simulate(mycode, myregisters, mydata, myrob, myiq) == 0){
      std::cout << "Simulator HALT encounted on cycle " << cycle << std::endl;
      quit(mycpu, myregisters, mydata, myrob, myiq);
      return 0;
    }

    if(VERBOSE >= 2){
	    mycpu.display();
	    myregisters.dUrf();
	  }
  }

  return 1;
}

//Quit the simulator
void quit(CPU &mycpu, Registers &myregisters, Data &mydata, ROB &myrob, IQ &myiq)
{
  if (VERBOSE >= 1)
    std::cout << "Quitting simulator ..." << std::endl;
  display(mycpu, myregisters, mydata, myrob, myiq, "all", 0, 100);
}
<commit_msg>Removed double header print out for stats<commit_after>/* FILE INFORMATION
File:     apex.cpp
Authors:  Matthew Cole <mcole8@binghamton.edu>
          Brian Gracin <bgracin1@binghamton.edu>
Description: Contains helper functions controlling simulator high-level behavior.
*/
#include <iostream>
#include "code.h"
#include "cpu.h"
#include "data.h"
#include "register.h"
#include "rob.h"
#include "iq.h"
#include "apex.h"

#define DEBUG 1

// Initialize simulator state and stats variables with external linkage
int cycle = 0;
int pc = 4000;
int dispatched = 0;
int no_dispatch = 0;
int issued = 0;
int no_issued = 0;
int committed = 0;
int committed_load = 0;
int committed_store = 0;
int no_commit= 0;

// Initialize simulator flags
int Z = 0;
int Zcycle = 0;

//Display an interface help message
void help()
{
  std::cout << "| Command        | Action\n"
            << "|----------------|---------------------------------------------\n"
            << "| i              |Initialize the simulator state\n"
            << "| s <n>          |Simulate <n> number of cycles\n"
            << "| dall           |Display the full simulator internal state\n"
            << "| dcpu           |Display CPU stage contents\n"
            << "| diq            |Display Issue Queue entries and status\n"
            << "| dmap           |Display Front-end, Back-end Register Tables\n"
            << "| dmem <a1> <a2> |Display memory from address <a1> to <a2>\n"
            << "| drob           |Display ROB contents\n"
            << "| dstats         |Display Stats\n"
            << "| durf           |Display Unified Register File\n"
            << "| urf <n>        |Set URF Size to <n> physical registers\n"
            << "| q              |Quit the simulator\n"
            << "| h              |Display this help message" << std::endl;
}

// Initialize the simulator to a known state.
void initialize(CPU &mycpu, Registers &myregisters, Data &mydata, ROB &myrob, IQ &myiq)
{
  if (VERBOSE >= 1)
    std::cout << "Initializing ... " << std::endl;

  //Reset simulator state and stats variables
  cycle = 0;
  pc = 4000;
  dispatched = 0;
  no_dispatch = 0;
  issued = 0;
  no_issued = 0;
  committed = 0;
  committed_load = 0;
  committed_store = 0;

  //Initialize each of the instances by delegating to member functions
  mycpu.initialize();
  myregisters.initialize();
  mydata.initialize();
} //end initialize()

// Display the simulator internal state.
void display(CPU &mycpu, Registers &myregisters, Data &mydata, ROB &myrob, IQ &myiq,
  std::string mod, int a1, int a2)
{
  //Sanitize inputs
  if  (mod != "all" &&
        mod != "cpu" &&
        mod != "iq"  &&
        mod != "map" &&
        mod != "mem" &&
        mod != "rob" &&
        mod != "stats" &&
        mod != "urf"){
            std::cerr << "Display modifier " << mod << " not understood.";
            mod = "";
  }
  if ((mod == "all" || mod == "mem") && a1 < 0){
    std::cerr << "Memory range start is out of bounds. Setting to 0." << std::endl;
    a1 = 0;
  }
  if ((mod == "all" || mod == "mem") && a2 > 3996){
    std::cerr << "Memory range stop is out of bounds. Setting to 3996." << std::endl;
    a2 = 3996;
  }
  if ((mod == "all" || mod == "mem") && (a1 > a2)){
    //We assert a1 <= a2. Swap a1, a2 if assertion is false.
    a1 = a1 ^ a2;
    a2 = a1 ^ a2;
    a1 = a1 ^ a2;
  }

  if (VERBOSE >= 1)
    std::cout << "Displaying simulator state ... " << std::endl;

  //Print simulator state variables
  std::cout << "cycle: " << cycle << " pc: " << pc << std::endl;

  //Display each of the instances by delegating to member functions
  if (mod == "all" || mod == "cpu"){
    if (VERBOSE >= 1)
      std::cout << "-----------\n" << "CPU\n" << "-----------\n";
    mycpu.display();
  }
  if (mod == "all" || mod == "iq"){
    if (VERBOSE >= 1)
      std::cout << "-----------\n" << "Issue Queue\n" << "-----------\n";
    myiq.display();
  }
  if (mod == "all" || mod == "map"){
    if (VERBOSE >= 1)
      std::cout << "-----------\n" << "Rename Tables\n" << "-----------\n";
    myregisters.dMap();
  }
  if (mod == "all" || mod == "mem"){
    if (VERBOSE >= 1)
      std::cout << "-----------\n" << "Data Memory\n" << "-----------\n";
    mydata.display(a1, a2);
  }
  if (mod == "all" || mod == "rob"){
    if (VERBOSE >= 1)
      std::cout << "-----------\n" << "Reorder Buffer\n" << "-----------\n";
    myrob.display();
  }
  if (mod == "all" || mod == "stats"){
    if (VERBOSE >= 1)
      std::cout << "-----------\n" << "Statistics\n" << "-----------\n";
    stats();
  }
  if (mod == "all" || mod == "urf"){
    if (VERBOSE >= 1)
      std::cout << "-----------\n" << "Registers\n" << "-----------\n";
    myregisters.dUrf();
  }
} // end display()

//Display simulator stats
void stats()
{
  std::cout << "Cycle: " << cycle << std::endl;
  std::cout << "Instructions through:\n"
            << " Dispatch=" << dispatched
            << " Issue=" << issued
            << " Commit=" << committed << std::endl;

  std::cout << "IPC: " << ((double) committed) / (double) cycle << std::endl;
  std::cout << "# cycles dispatch stalled: " << no_dispatch << std::endl;
  std::cout << "# cycles with no issue: " << no_issued << std::endl;
  std::cout << "# LOAD instructions committed: " << committed_load << std::endl;
  std::cout << "# STORE instructions committed: " << committed_store << std::endl;
  std::cout << "# cycles with no commit: " << no_commit << std::endl;
}

// Simulate the operation of the system for <num_cycles>, or until a HALT
//instruction is encountered, or until an error occurs in simulation.
//Return the current cycle number after simulation pauses or halts.
int simulate(int num_cycles, CPU &mycpu, Code &mycode, Registers &myregisters,
  Data &mydata, ROB &myrob, IQ &myiq)
{
  int start = ::cycle;
  int stop = ::cycle + num_cycles;

  for (int c = start; c < stop; c++)
  {
    //Perform one cycle of simulation
    if (VERBOSE >= 1)
      std::cout << "Simulating cycle " << cycle << " ..." << std::endl;

    #if (DEBUG)
      mycpu.display();
      //myregisters.dMap();
      //myregisters.dUrf();
      mydata.display(0, 100);
    #endif

    //cpu::simulate() returns 0 if execution should not continue
    //(EOF, HALT or exception encountered)
    if(mycpu.simulate(mycode, myregisters, mydata, myrob, myiq) == 0){
      std::cout << "Simulator HALT encounted on cycle " << cycle << std::endl;
      quit(mycpu, myregisters, mydata, myrob, myiq);
      return 0;
    }

    if(VERBOSE >= 2){
	    mycpu.display();
	    myregisters.dUrf();
	  }
  }

  return 1;
}

//Quit the simulator
void quit(CPU &mycpu, Registers &myregisters, Data &mydata, ROB &myrob, IQ &myiq)
{
  if (VERBOSE >= 1)
    std::cout << "Quitting simulator ..." << std::endl;
  display(mycpu, myregisters, mydata, myrob, myiq, "all", 0, 100);
}
<|endoftext|>


<commit_before>#ifndef GNR_COROUTINE_HPP
# define GNR_COROUTINE_HPP
# pragma once

#include <cassert>

#include <cstdint>

#include <functional>

#include <memory>

#include "savestate.hpp"

namespace gnr
{

namespace
{

enum : std::size_t { anon_default_stack_size = 512 * 1024 };

}

template <
  std::size_t N = anon_default_stack_size,
  template <typename> class Function = std::function
>
class coroutine
{
public:
  enum : std::size_t { default_stack_size = anon_default_stack_size };
  enum : std::size_t { stack_size = N };

  enum status : std::uint8_t
  {
    INITIALIZED,
    RUNNING,
    TERMINATED
  };

private:
  statebuf env_in_;
  statebuf env_out_;

  enum status status_{TERMINATED};

  std::unique_ptr<char[]> stack_;

  Function<void()> f_;

public:
  explicit coroutine() :
    stack_(new char[stack_size])
  {
  }

  template <typename F>
  explicit coroutine(F&& f) :
    coroutine()
  {
    assign(std::forward<F>(f));
  }

  coroutine(coroutine&&) = default;

  coroutine& operator=(coroutine&&) = default;

  template <typename F>
  coroutine& operator=(F&& f)
  {
    assign(std::forward<F>(f));

    return *this;
  }

  auto status() const noexcept
  {
    return status_;
  }

  auto is_terminated() const noexcept
  {
    return TERMINATED == status_;
  }

  template <typename F>
  void assign(F&& f)
  {
    f_ = [this, f = std::forward<F>(f)]()
      {
        status_ = RUNNING;

        f(*this);

        status_ = TERMINATED;

        yield();
      };

    status_ = INITIALIZED;
  }

#if defined(__GNUC__)
  void yield() noexcept __attribute__ ((noinline))
#elif defined(_MSC_VER)
  __declspec(noinline) void yield() noexcept
#else
# error "unsupported compiler"
#endif
  {
#if defined(__GNUC__)
#if defined(i386) || defined(__i386) || defined(__i386__)
    asm volatile ("":::"eax", "ebx", "ecx", "edx", "esi", "edi");
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
    asm volatile ("":::"rax", "rbx", "rcx", "rdx", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15");
#elif defined(__arm__)
    asm volatile ("":::"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11");
#endif
#endif

    if (!savestate(env_out_))
    {
      restorestate(env_in_);
    }
    // else do nothing
  }

#if defined(__GNUC__)
  void resume() noexcept __attribute__ ((noinline))
#elif defined(_MSC_VER)
  __declspec(noinline) void resume() noexcept
#else
# error "unsupported compiler"
#endif
  {
#if defined(__GNUC__)
#if defined(i386) || defined(__i386) || defined(__i386__)
    asm volatile ("":::"eax", "ebx", "ecx", "edx", "esi", "edi");
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
    asm volatile ("":::"rax", "rbx", "rcx", "rdx", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15");
#elif defined(__arm__)
    asm volatile ("":::"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11");
#endif
#endif

    assert(TERMINATED != status());
    if (savestate(env_in_))
    {
      return;
    }
    else if (RUNNING == status())
    {
      restorestate(env_out_);
    }
    else
    {
#if defined(__GNUC__)
      // stack switch
#if defined(i386) || defined(__i386) || defined(__i386__)
      asm volatile(
        "movl %0, %%esp"
        :
        : "r" (stack_.get() + stack_size)
      );
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
      asm volatile(
        "movq %0, %%rsp"
        :
        : "r" (stack_.get() + stack_size)
      );
#elif defined(__arm__)
      asm volatile(
        "mov sp, %0"
        :
        : "r" (stack_.get() + stack_size)
      );
#else
#error "can't switch stack frame"
#endif
#elif defined(_MSC_VER)
    auto const p(stack_.get() + stack_size);

    _asm mov esp, p
#else
#error "can't switch stack frame"
#endif
      f_();
    }
  }
};

}

#endif // GNR_COROUTINE_HPP
<commit_msg>some fixes<commit_after>#ifndef GNR_COROUTINE_HPP
# define GNR_COROUTINE_HPP
# pragma once

#include <cassert>

#include <cstdint>

#include <functional>

#include <memory>

#include "savestate.hpp"

namespace gnr
{

namespace
{

enum : std::size_t { anon_default_stack_size = 512 * 1024 };

}

template <
  std::size_t N = anon_default_stack_size,
  template <typename> class Function = std::function
>
class coroutine
{
public:
  enum : std::size_t { default_stack_size = anon_default_stack_size };
  enum : std::size_t { stack_size = N };

  enum status : std::uint8_t
  {
    INITIALIZED,
    RUNNING,
    TERMINATED
  };

private:
  statebuf env_in_;
  statebuf env_out_;

  enum status status_{TERMINATED};

  std::unique_ptr<char[]> stack_;

  Function<void()> f_;

public:
  explicit coroutine() :
    stack_(new char[stack_size])
  {
  }

  template <typename F>
  explicit coroutine(F&& f) :
    coroutine()
  {
    assign(std::forward<F>(f));
  }

  coroutine(coroutine&&) = default;

  coroutine& operator=(coroutine&&) = default;

  template <typename F>
  coroutine& operator=(F&& f)
  {
    assign(std::forward<F>(f));

    return *this;
  }

  auto status() const noexcept
  {
    return status_;
  }

  auto is_terminated() const noexcept
  {
    return TERMINATED == status_;
  }

  template <typename F>
  void assign(F&& f)
  {
    f_ = [this, f = std::forward<F>(f)]()
      {
        status_ = RUNNING;

        f(*this);

        status_ = TERMINATED;

        yield();
      };

    status_ = INITIALIZED;
  }

#if defined(__GNUC__)
  void yield() noexcept __attribute__ ((noinline))
#elif defined(_MSC_VER)
  __declspec(noinline) void yield() noexcept
#else
# error "unsupported compiler"
#endif
  {
#if defined(__GNUC__)
#if defined(i386) || defined(__i386) || defined(__i386__)
    asm volatile ("":::"eax", "ebx", "ecx", "edx", "esi", "edi");
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
    asm volatile ("":::"rax", "rbx", "rcx", "rdx", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15");
#elif defined(__arm__)
    asm volatile ("":::"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8");
#endif
#endif

    if (!savestate(env_out_))
    {
      restorestate(env_in_);
    }
    // else do nothing
  }

#if defined(__GNUC__)
  void resume() noexcept __attribute__ ((noinline))
#elif defined(_MSC_VER)
  __declspec(noinline) void resume() noexcept
#else
# error "unsupported compiler"
#endif
  {
#if defined(__GNUC__)
#if defined(i386) || defined(__i386) || defined(__i386__)
    asm volatile ("":::"eax", "ebx", "ecx", "edx", "esi", "edi");
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
    asm volatile ("":::"rax", "rbx", "rcx", "rdx", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15");
#elif defined(__arm__)
    asm volatile ("":::"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8");
#endif
#endif

    assert(TERMINATED != status());
    if (savestate(env_in_))
    {
      return;
    }
    else if (RUNNING == status())
    {
      restorestate(env_out_);
    }
    else
    {
#if defined(__GNUC__)
      // stack switch
#if defined(i386) || defined(__i386) || defined(__i386__)
      asm volatile(
        "movl %0, %%esp"
        :
        : "r" (stack_.get() + stack_size)
      );
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
      asm volatile(
        "movq %0, %%rsp"
        :
        : "r" (stack_.get() + stack_size)
      );
#elif defined(__arm__)
      asm volatile(
        "mov sp, %0"
        :
        : "r" (stack_.get() + stack_size)
      );
#else
#error "can't switch stack frame"
#endif
#elif defined(_MSC_VER)
    auto const p(stack_.get() + stack_size);

    _asm mov esp, p
#else
#error "can't switch stack frame"
#endif
      f_();
    }
  }
};

}

#endif // GNR_COROUTINE_HPP
<|endoftext|>


<commit_before>#ifndef GNR_COROUTINE_HPP
# define GNR_COROUTINE_HPP
# pragma once

#include <cassert>

#include <cstdint>

#include <functional>

#include <memory>

#include "savestate.hpp"

namespace gnr
{

namespace
{

enum : std::size_t { anon_default_stack_size = 512 * 1024 };

}

template <
  std::size_t N = anon_default_stack_size,
  template <typename> class Function = std::function
>
class coroutine
{
public:
  enum : std::size_t { default_stack_size = anon_default_stack_size };
  enum : std::size_t { stack_size = N };

  enum status : std::uint8_t
  {
    INITIALIZED,
    RUNNING,
    TERMINATED
  };

private:
  statebuf env_in_;
  statebuf env_out_;

  enum status status_{TERMINATED};

  std::unique_ptr<char[]> stack_;

  Function<void()> f_;

public:
  explicit coroutine() :
    stack_(new char[stack_size])
  {
  }

  template <typename F>
  explicit coroutine(F&& f) :
    coroutine()
  {
    assign(std::forward<F>(f));
  }

  coroutine(coroutine&&) = default;

  coroutine& operator=(coroutine&&) = default;

  template <typename F>
  coroutine& operator=(F&& f)
  {
    assign(std::forward<F>(f));

    return *this;
  }

  auto status() const noexcept
  {
    return status_;
  }

  auto is_terminated() const noexcept
  {
    return TERMINATED == status_;
  }

  template <typename F>
  void assign(F&& f)
  {
    f_ = [this, f = std::forward<F>(f)]()
      {
        status_ = RUNNING;

        f(*this);

        status_ = TERMINATED;

        yield();
      };

    status_ = INITIALIZED;
  }

#if defined(__GNUC__)
  void yield() noexcept __attribute__ ((noinline))
#elif defined(_MSC_VER)
  __declspec(noinline) void yield() noexcept
#else
# error "unsupported compiler"
#endif
  {
#if defined(__GNUC__)
#if defined(i386) || defined(__i386) || defined(__i386__)
    asm volatile ("":::"eax", "ebx", "ecx", "edx", "esi", "edi");
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
    asm volatile ("":::"rax", "rbx", "rcx", "rdx", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15");
#elif defined(__arm__)
    asm volatile ("":::"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr");
#endif
#endif

    if (!savestate(env_out_))
    {
      restorestate(env_in_);
    }
    // else do nothing
  }

#if defined(__GNUC__)
  void resume() noexcept __attribute__ ((noinline))
#elif defined(_MSC_VER)
  __declspec(noinline) void resume() noexcept
#else
# error "unsupported compiler"
#endif
  {
#if defined(__GNUC__)
#if defined(i386) || defined(__i386) || defined(__i386__)
    asm volatile ("":::"eax", "ebx", "ecx", "edx", "esi", "edi");
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
    asm volatile ("":::"rax", "rbx", "rcx", "rdx", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15");
#elif defined(__arm__)
    asm volatile ("":::"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr");
#endif
#endif

    assert(TERMINATED != status());
    if (savestate(env_in_))
    {
      return;
    }
    else if (RUNNING == status())
    {
      restorestate(env_out_);
    }
    else
    {
#if defined(__GNUC__)
      // stack switch
#if defined(i386) || defined(__i386) || defined(__i386__)
      asm volatile(
        "movl %0, %%esp"
        :
        : "r" (stack_.get() + stack_size)
      );
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
      asm volatile(
        "movq %0, %%rsp"
        :
        : "r" (stack_.get() + stack_size)
      );
#elif defined(__arm__)
      asm volatile(
        "mov sp, %0"
        :
        : "r" (stack_.get() + stack_size)
      );
#else
#error "can't switch stack frame"
#endif
#elif defined(_MSC_VER)
    auto const p(stack_.get() + stack_size);

    _asm mov esp, p
#else
#error "can't switch stack frame"
#endif
      f_();
    }
  }
};

}

#endif // GNR_COROUTINE_HPP
<commit_msg>some fixes<commit_after>#ifndef GNR_COROUTINE_HPP
# define GNR_COROUTINE_HPP
# pragma once

#include <cassert>

#include <cstdint>

#include <functional>

#include <memory>

#include "savestate.hpp"

namespace gnr
{

namespace
{

// half a megabyte stack default
enum : std::size_t { anon_default_stack_size = 512 * 1024 };

}

template <
  std::size_t N = anon_default_stack_size,
  template <typename> class Function = std::function
>
class coroutine
{
public:
  enum : std::size_t { default_stack_size = anon_default_stack_size };
  enum : std::size_t { stack_size = N };

  enum status : std::uint8_t
  {
    INITIALIZED,
    RUNNING,
    TERMINATED
  };

private:
  statebuf env_in_;
  statebuf env_out_;

  enum status status_{TERMINATED};

  std::unique_ptr<char[]> stack_;

  Function<void()> f_;

public:
  explicit coroutine() :
    stack_(new char[stack_size])
  {
  }

  template <typename F>
  explicit coroutine(F&& f) :
    coroutine()
  {
    assign(std::forward<F>(f));
  }

  coroutine(coroutine&&) = default;

  coroutine& operator=(coroutine&&) = default;

  template <typename F>
  coroutine& operator=(F&& f)
  {
    assign(std::forward<F>(f));

    return *this;
  }

  auto status() const noexcept
  {
    return status_;
  }

  auto is_terminated() const noexcept
  {
    return TERMINATED == status_;
  }

  template <typename F>
  void assign(F&& f)
  {
    f_ = [this, f = std::forward<F>(f)]()
      {
        status_ = RUNNING;

        f(*this);

        status_ = TERMINATED;

        yield();
      };

    status_ = INITIALIZED;
  }

#if defined(__GNUC__)
  void yield() noexcept __attribute__ ((noinline))
#elif defined(_MSC_VER)
  __declspec(noinline) void yield() noexcept
#else
# error "unsupported compiler"
#endif
  {
#if defined(__GNUC__)
#if defined(i386) || defined(__i386) || defined(__i386__)
    asm volatile ("":::"eax", "ebx", "ecx", "edx", "esi", "edi");
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
    asm volatile ("":::"rax", "rbx", "rcx", "rdx", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15");
#elif defined(__arm__)
    asm volatile ("":::"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr");
#endif
#endif

    if (!savestate(env_out_))
    {
      restorestate(env_in_);
    }
    // else do nothing
  }

#if defined(__GNUC__)
  void resume() noexcept __attribute__ ((noinline))
#elif defined(_MSC_VER)
  __declspec(noinline) void resume() noexcept
#else
# error "unsupported compiler"
#endif
  {
#if defined(__GNUC__)
#if defined(i386) || defined(__i386) || defined(__i386__)
    asm volatile ("":::"eax", "ebx", "ecx", "edx", "esi", "edi");
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
    asm volatile ("":::"rax", "rbx", "rcx", "rdx", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15");
#elif defined(__arm__)
    asm volatile ("":::"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr");
#endif
#endif

    assert(TERMINATED != status());
    if (savestate(env_in_))
    {
      return;
    }
    else if (RUNNING == status())
    {
      restorestate(env_out_);
    }
    else
    {
#if defined(__GNUC__)
      // stack switch
#if defined(i386) || defined(__i386) || defined(__i386__)
      asm volatile(
        "movl %0, %%esp"
        :
        : "r" (stack_.get() + stack_size)
      );
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
      asm volatile(
        "movq %0, %%rsp"
        :
        : "r" (stack_.get() + stack_size)
      );
#elif defined(__arm__)
      asm volatile(
        "mov sp, %0"
        :
        : "r" (stack_.get() + stack_size)
      );
#else
#error "can't switch stack frame"
#endif
#elif defined(_MSC_VER)
    auto const p(stack_.get() + stack_size);

    _asm mov esp, p
#else
#error "can't switch stack frame"
#endif
      f_();
    }
  }
};

}

#endif // GNR_COROUTINE_HPP
<|endoftext|>


<commit_before>
#include "stdafx.h"
#include "fixes.h"
#include "addresses.h"
#include "dependencies/python-2.2/Python.h"
#include "temple_functions.h""

/*
	Define all type objects used by ToEE.
*/
// ObjHandle
	static GlobalStruct<PyTypeObject, 0x102CF3B8> pyObjHandleType;
	static getattrfunc pyObjHandleTypeGetAttr; // Original getattr of pyObjHandleType
	static setattrfunc pyObjHandleTypeSetAttr; // Original setattr of pyObjHandleType
	static GlobalStruct<PyMethodDef, 0x102CE9A8> pyObjHandleMethods;
	//PyCFunction a[]; // this causes errors during compile!

	static PyMethodDef pyObjHandleMethods_New[] = {
		"faction_has", (PyCFunction)pyObjHandleType_Faction_Has, METH_VARARGS, "Check if NPC has faction. Doesn't work on PCs!",
		"faction_has2", (PyCFunction)pyObjHandleType_Faction_Has, METH_VARARGS, "Check if NPC has faction. Doesn't work on PCs!",
		0,0,0,0
	};

	static PyObject * pyObjHandleType_Faction_Has(PyObject* obj, PyObject * pyTupleIn){
		int nFac;
		if (!PyArg_ParseTuple(pyTupleIn, "i", &nFac)) {
			return nullptr;
		}
		return PyInt_FromLong(templeFuncs.Obj_Faction_Has((TemplePyObjHandle*)obj->objHandle, nFac));
	};

struct ObjectId {
	uint16_t subtype;
	GUID guid;
};

struct TemplePyObjHandle : public PyObject {
	ObjectId objId;
	uint64_t objHandle;
};

PyObject* __cdecl  pyObjHandleType_getAttrNew(TemplePyObjHandle *obj, char *name) {
	LOG(info) << "Tried getting property: " << name;
	if (!_strcmpi(name, "co8rocks")) {
		return PyString_FromString("IT SURE DOES!");
	}

	if (!_strcmpi(name, "ObjHandle")) {
		return  PyLong_FromLongLong(obj->objHandle);
	}

	if (!_strcmpi(name, "factions")) {
		ObjHndl ObjHnd = obj->objHandle;
		int a[50] = {};
		int n = 0;

		for (int i = 0; i < 50; i ++){
			int fac = templeFuncs.Obj_Get_IdxField_32bit(ObjHnd, obj_f_npc_faction, i);
			if (fac == 0) break;
			a[i] = fac;
			n++;
		};

		auto outTup = PyTuple_New(n);
		for (int i = 0; i < n ; i++){
			PyTuple_SetItem(outTup, i, PyInt_FromLong(a[i]));
		};

		return  outTup;
	}

	if (!_strcmpi(name, "faction_has")) {
		//ObjHndl ObjSubsInv = templeFuncs.Obj_Get_Substitute_Inventory(obj->objHandle);

		return Py_FindMethod(pyObjHandleMethods_New, obj, "faction_has");

	}

	if (!_strcmpi(name, "substitute_inventory")) {
		ObjHndl ObjSubsInv = templeFuncs.Obj_Get_Substitute_Inventory(obj->objHandle);
		return templeFuncs.PyObj_From_ObjHnd(ObjSubsInv);
	}

	if (!_strcmpi(name, "obj_get_field_64")) {

		return 0;
	}

	return pyObjHandleTypeGetAttr(obj, name);
}

int __cdecl  pyObjHandleType_setAttrNew(TemplePyObjHandle *obj, char *name, TemplePyObjHandle *obj2) {
	LOG(info) << "Tried setting property: " << name;
	if (!strcmp(name, "co8rocks")) {
		return 0;
	}

	if (!strcmp(name, "substitute_inventory")) {

		if (obj2 != nullptr)  {
			if (obj->ob_type == obj2->ob_type){
				templeFuncs.Obj_Set_Field_ObjHnd(obj->objHandle, 365, obj2->objHandle);
			}

		}

		return 0;
	}

	return pyObjHandleTypeSetAttr(obj, name, obj2);
}

class PythonExtensions : public TempleFix {
public:
	const char* name() override {
		return "Python Script Extensions";
	}
	void apply() override;
} pythonExtension;

void PythonExtensions::apply() {

	// Hook the getattr function of obj handles
	pyObjHandleTypeGetAttr = pyObjHandleType->tp_getattr;
	pyObjHandleType->tp_getattr = (getattrfunc) pyObjHandleType_getAttrNew;

	pyObjHandleTypeSetAttr = pyObjHandleType->tp_setattr;
	pyObjHandleType->tp_setattr = (setattrfunc) pyObjHandleType_setAttrNew;

	//a[0] = pyObjHandleMethods->ml_meth;

}
<commit_msg>Python pt2<commit_after>
#include "stdafx.h"
#include "fixes.h"
#include "addresses.h"
#include "dependencies/python-2.2/Python.h"
#include "temple_functions.h""

/*
	Define all type objects used by ToEE.
*/
// ObjHandle
	static GlobalStruct<PyTypeObject, 0x102CF3B8> pyObjHandleType;
	static getattrfunc pyObjHandleTypeGetAttr; // Original getattr of pyObjHandleType
	static setattrfunc pyObjHandleTypeSetAttr; // Original setattr of pyObjHandleType
	static GlobalStruct<PyMethodDef, 0x102CE9A8> pyObjHandleMethods;
	//PyCFunction a[]; // this causes errors during compile!

struct ObjectId {
	uint16_t subtype;
	GUID guid;
};

struct TemplePyObjHandle : public PyObject {
	ObjectId objId;
	uint64_t objHandle;
};

static PyObject * pyObjHandleType_Faction_Has(TemplePyObjHandle* obj, PyObject * pyTupleIn){
	int nFac;
	if (!PyArg_ParseTuple(pyTupleIn, "i", &nFac)) {
		return nullptr;
	};
	//auto dude = (TemplePyObjHandle*)obj;

	//return PyInt_FromLong(templeFuncs.Obj_Faction_Has(dude->objHandle, nFac));
	return PyInt_FromLong(templeFuncs.Obj_Faction_Has(obj->objHandle, nFac));
};

static PyMethodDef pyObjHandleMethods_New[] = {
	"faction_has", (PyCFunction)pyObjHandleType_Faction_Has, METH_VARARGS, "Check if NPC has faction. Doesn't work on PCs!",
	"faction_has2", (PyCFunction)pyObjHandleType_Faction_Has, METH_VARARGS, "Check if NPC has faction. Doesn't work on PCs!",
	0, 0, 0, 0
};

PyObject* __cdecl  pyObjHandleType_getAttrNew(TemplePyObjHandle *obj, char *name) {
	LOG(info) << "Tried getting property: " << name;
	if (!_strcmpi(name, "co8rocks")) {
		return PyString_FromString("IT SURE DOES!");
	}

	if (!_strcmpi(name, "ObjHandle")) {
		return  PyLong_FromLongLong(obj->objHandle);
	}

	if (!_strcmpi(name, "factions")) {
		ObjHndl ObjHnd = obj->objHandle;
		int a[50] = {};
		int n = 0;

		for (int i = 0; i < 50; i ++){
			int fac = templeFuncs.Obj_Get_IdxField_32bit(ObjHnd, obj_f_npc_faction, i);
			if (fac == 0) break;
			a[i] = fac;
			n++;
		};

		auto outTup = PyTuple_New(n);
		for (int i = 0; i < n ; i++){
			PyTuple_SetItem(outTup, i, PyInt_FromLong(a[i]));
		};

		return  outTup;
	}

	if (!_strcmpi(name, "faction_has")) {
		//ObjHndl ObjSubsInv = templeFuncs.Obj_Get_Substitute_Inventory(obj->objHandle);

		return Py_FindMethod(pyObjHandleMethods_New, obj, "faction_has");

	}

	if (!_strcmpi(name, "substitute_inventory")) {
		ObjHndl ObjSubsInv = templeFuncs.Obj_Get_Substitute_Inventory(obj->objHandle);
		return templeFuncs.PyObj_From_ObjHnd(ObjSubsInv);
	}

	if (!_strcmpi(name, "obj_get_field_64")) {

		return 0;
	}

	return pyObjHandleTypeGetAttr(obj, name);
}

int __cdecl  pyObjHandleType_setAttrNew(TemplePyObjHandle *obj, char *name, TemplePyObjHandle *obj2) {
	LOG(info) << "Tried setting property: " << name;
	if (!strcmp(name, "co8rocks")) {
		return 0;
	}

	if (!strcmp(name, "substitute_inventory")) {

		if (obj2 != nullptr)  {
			if (obj->ob_type == obj2->ob_type){
				templeFuncs.Obj_Set_Field_ObjHnd(obj->objHandle, obj_f_npc_substitute_inventory, obj2->objHandle);
			}

		}

		return 0;
	}

	return pyObjHandleTypeSetAttr(obj, name, obj2);
}

class PythonExtensions : public TempleFix {
public:
	const char* name() override {
		return "Python Script Extensions";
	}
	void apply() override;
} pythonExtension;

void PythonExtensions::apply() {

	// Hook the getattr function of obj handles
	pyObjHandleTypeGetAttr = pyObjHandleType->tp_getattr;
	pyObjHandleType->tp_getattr = (getattrfunc) pyObjHandleType_getAttrNew;

	pyObjHandleTypeSetAttr = pyObjHandleType->tp_setattr;
	pyObjHandleType->tp_setattr = (setattrfunc) pyObjHandleType_setAttrNew;

	//a[0] = pyObjHandleMethods->ml_meth;

}
<|endoftext|>


<commit_before>// Module:  Log4CPLUS
// File:    property.cxx
// Created: 2/2002
// Author:  Tad E. Smith
//
//
// Copyright (C) Tad E. Smith  All rights reserved.
//
// This software is published under the terms of the Apache Software
// License version 1.1, a copy of which has been included with this
// distribution in the LICENSE.APL file.
//
// $Log: not supported by cvs2svn $
// Revision 1.11  2003/06/09 23:06:54  tcsmith
// Added support for "comment" lines in the property file.
//
// Revision 1.10  2003/05/19 15:58:26  tcsmith
// Added a check in the ctor for a valid filename.  If if is not valid, do
// not attempt to open that file.
//
// Revision 1.9  2003/05/01 19:54:30  tcsmith
// Fixed: "warning: comparison between signed and unsigned".
//
// Revision 1.8  2003/05/01 19:35:25  tcsmith
// Fixed VC++ compiler "performance warning".
//
// Revision 1.7  2003/04/19 23:04:32  tcsmith
// Fixed UNICODE support.
//
// Revision 1.6  2003/04/18 21:52:35  tcsmith
// Converted from using std::ifstream to using log4cplus::tifstream.
//
// Revision 1.5  2003/04/18 21:32:22  tcsmith
// Converted from std::string to log4cplus::tstring.
//
// Revision 1.4  2003/04/05 20:09:17  tcsmith
// Added the removeProperty() method.
//
// Revision 1.3  2003/04/03 01:23:34  tcsmith
// Standardized the formatting.
//

#include <log4cplus/helpers/property.h>
#include <log4cplus/fstreams.h>

using namespace std;
using namespace log4cplus;

#define BUFFER_SIZE 2048

const tchar helpers::Properties::PROPERTIES_COMMENT_CHAR = LOG4CPLUS_TEXT('#');

///////////////////////////////////////////////////////////////////////////////
// log4cplus::helpers::Properties ctors and dtor
///////////////////////////////////////////////////////////////////////////////

log4cplus::helpers::Properties::Properties()
{
}

log4cplus::helpers::Properties::Properties(log4cplus::tistream& input)
{
    init(input);
}

log4cplus::helpers::Properties::Properties(const log4cplus::tstring& inputFile)
{
    if(inputFile.length() == 0) {
        return;
    }

    tifstream file;
    file.open(LOG4CPLUS_TSTRING_TO_STRING(inputFile).c_str());
    if(!file) {
        return;
    }
    init(file);
}

void
log4cplus::helpers::Properties::init(log4cplus::tistream& input)
{
    if(input.fail()) {
        return;
    }

    tchar buffer[BUFFER_SIZE];
    while(!input.eof()) {
        input.getline(buffer, BUFFER_SIZE);
        if(buffer[0] != PROPERTIES_COMMENT_CHAR)
        {
            // Check if we have a trailing \r because we are
            // reading a properties file produced on Windows.
            int buffLen = strlen(buffer);
            if((buffLen > 0) && buffer[buffLen-1] == '\r') {
                // Remove trailing 'Windows' \r
                buffer[buffLen-1] = '\0';
            }

            tstring tmp(buffer);
            tstring::size_type idx = tmp.find('=');
            if(idx != tstring::npos) {
                setProperty(tmp.substr(0, idx), tmp.substr(idx + 1));
            }
        }
    }
}

log4cplus::helpers::Properties::~Properties()
{
}

///////////////////////////////////////////////////////////////////////////////
// log4cplus::helpers::Properties public methods
///////////////////////////////////////////////////////////////////////////////

tstring
log4cplus::helpers::Properties::getProperty(const tstring& key) const
{
    StringMap::const_iterator it = data.find(key);
    if(it == data.end()) {
        return LOG4CPLUS_TEXT("");
    }
    else {
        return it->second;
    }
}

tstring
log4cplus::helpers::Properties::getProperty(const tstring& key,
                                            const tstring& defaultVal) const
{
    if(exists(key)) {
        return getProperty(key);
    }
    else {
        return defaultVal;
    }
}

vector<tstring>
log4cplus::helpers::Properties::propertyNames() const
{
    vector<tstring> tmp;
    for(StringMap::const_iterator it=data.begin(); it!=data.end(); ++it) {
        tmp.push_back(it->first);
    }

    return tmp;
}

void
log4cplus::helpers::Properties::setProperty(const log4cplus::tstring& key,
                                            const log4cplus::tstring& value)
{
    data[key] = value;
}

bool
log4cplus::helpers::Properties::removeProperty(const log4cplus::tstring& key)
{
    return (data.erase(key) > 0);
}

log4cplus::helpers::Properties
log4cplus::helpers::Properties::getPropertySubset(const log4cplus::tstring& prefix) const
{
    Properties ret;

    vector<tstring> keys = propertyNames();
    for(vector<tstring>::iterator it=keys.begin(); it!=keys.end(); ++it) {
        tstring::size_type pos = (*it).find(prefix);
        if(pos != tstring::npos) {
            ret.setProperty( (*it).substr(prefix.size()), getProperty(*it) );
        }
    }

    return ret;
}

<commit_msg>Fixed UNICODE support.<commit_after>// Module:  Log4CPLUS
// File:    property.cxx
// Created: 2/2002
// Author:  Tad E. Smith
//
//
// Copyright (C) Tad E. Smith  All rights reserved.
//
// This software is published under the terms of the Apache Software
// License version 1.1, a copy of which has been included with this
// distribution in the LICENSE.APL file.
//
// $Log: not supported by cvs2svn $
// Revision 1.12  2003/10/22 05:46:38  tcsmith
// Now strip trailing \r.  (A property file can be created on Windows and used
// on *nix.)
//
// Revision 1.11  2003/06/09 23:06:54  tcsmith
// Added support for "comment" lines in the property file.
//
// Revision 1.10  2003/05/19 15:58:26  tcsmith
// Added a check in the ctor for a valid filename.  If if is not valid, do
// not attempt to open that file.
//
// Revision 1.9  2003/05/01 19:54:30  tcsmith
// Fixed: "warning: comparison between signed and unsigned".
//
// Revision 1.8  2003/05/01 19:35:25  tcsmith
// Fixed VC++ compiler "performance warning".
//
// Revision 1.7  2003/04/19 23:04:32  tcsmith
// Fixed UNICODE support.
//
// Revision 1.6  2003/04/18 21:52:35  tcsmith
// Converted from using std::ifstream to using log4cplus::tifstream.
//
// Revision 1.5  2003/04/18 21:32:22  tcsmith
// Converted from std::string to log4cplus::tstring.
//
// Revision 1.4  2003/04/05 20:09:17  tcsmith
// Added the removeProperty() method.
//
// Revision 1.3  2003/04/03 01:23:34  tcsmith
// Standardized the formatting.
//

#include <log4cplus/helpers/property.h>
#include <log4cplus/fstreams.h>

using namespace std;
using namespace log4cplus;

#define BUFFER_SIZE 2048

const tchar helpers::Properties::PROPERTIES_COMMENT_CHAR = LOG4CPLUS_TEXT('#');

///////////////////////////////////////////////////////////////////////////////
// log4cplus::helpers::Properties ctors and dtor
///////////////////////////////////////////////////////////////////////////////

log4cplus::helpers::Properties::Properties()
{
}

log4cplus::helpers::Properties::Properties(log4cplus::tistream& input)
{
    init(input);
}

log4cplus::helpers::Properties::Properties(const log4cplus::tstring& inputFile)
{
    if(inputFile.length() == 0) {
        return;
    }

    tifstream file;
    file.open(LOG4CPLUS_TSTRING_TO_STRING(inputFile).c_str());
    if(!file) {
        return;
    }
    init(file);
}

void
log4cplus::helpers::Properties::init(log4cplus::tistream& input)
{
    if(input.fail()) {
        return;
    }

    tchar buffer[BUFFER_SIZE];
    while(!input.eof()) {
        input.getline(buffer, BUFFER_SIZE);
        if(buffer[0] != PROPERTIES_COMMENT_CHAR)
        {
            // Check if we have a trailing \r because we are
            // reading a properties file produced on Windows.
            size_t buffLen =
#ifdef UNICODE
				wcslen(buffer);
#else
				strlen(buffer);
#endif
            if((buffLen > 0) && buffer[buffLen-1] == '\r') {
                // Remove trailing 'Windows' \r
                buffer[buffLen-1] = '\0';
            }

            tstring tmp(buffer);
            tstring::size_type idx = tmp.find('=');
            if(idx != tstring::npos) {
                setProperty(tmp.substr(0, idx), tmp.substr(idx + 1));
            }
        }
    }
}

log4cplus::helpers::Properties::~Properties()
{
}

///////////////////////////////////////////////////////////////////////////////
// log4cplus::helpers::Properties public methods
///////////////////////////////////////////////////////////////////////////////

tstring
log4cplus::helpers::Properties::getProperty(const tstring& key) const
{
    StringMap::const_iterator it = data.find(key);
    if(it == data.end()) {
        return LOG4CPLUS_TEXT("");
    }
    else {
        return it->second;
    }
}

tstring
log4cplus::helpers::Properties::getProperty(const tstring& key,
                                            const tstring& defaultVal) const
{
    if(exists(key)) {
        return getProperty(key);
    }
    else {
        return defaultVal;
    }
}

vector<tstring>
log4cplus::helpers::Properties::propertyNames() const
{
    vector<tstring> tmp;
    for(StringMap::const_iterator it=data.begin(); it!=data.end(); ++it) {
        tmp.push_back(it->first);
    }

    return tmp;
}

void
log4cplus::helpers::Properties::setProperty(const log4cplus::tstring& key,
                                            const log4cplus::tstring& value)
{
    data[key] = value;
}

bool
log4cplus::helpers::Properties::removeProperty(const log4cplus::tstring& key)
{
    return (data.erase(key) > 0);
}

log4cplus::helpers::Properties
log4cplus::helpers::Properties::getPropertySubset(const log4cplus::tstring& prefix) const
{
    Properties ret;

    vector<tstring> keys = propertyNames();
    for(vector<tstring>::iterator it=keys.begin(); it!=keys.end(); ++it) {
        tstring::size_type pos = (*it).find(prefix);
        if(pos != tstring::npos) {
            ret.setProperty( (*it).substr(prefix.size()), getProperty(*it) );
        }
    }

    return ret;
}

<|endoftext|>


<commit_before>/*
 * Define functions for finding prime numbers.
 */

#include <algorithm>
#include <cmath>
#include <cstddef>
#include <vector>

using Long = unsigned long long int;

// Internal function, do not use.
void do_sieve(std::vector<Long> &primes, std::vector<char> &mark, Long &offset,
        Long limit, std::size_t maxSegmentSize) {
    auto sq = [](Long x) { return x * x; };

    std::size_t segmentSize = std::min<Long>(sq(primes.back()), limit) - offset;
    segmentSize = std::min(segmentSize, maxSegmentSize);

    mark.reserve(segmentSize);
    std::fill_n(mark.begin(), segmentSize, 1);
    for(auto it = primes.begin(); sq(*it) < offset + segmentSize; ++it) {
        // Round up to the next multiple of *it >= offset
        auto start = ((offset + *it - 1) / *it) * *it;
        for(auto idx = start - offset; idx < segmentSize; idx += *it) {
            mark[idx] = 0;
        }
    }
    for(std::size_t j = 0; j < segmentSize; j++) {
        if(mark[j]) {
            primes.push_back(offset + j);
        }
    }
    offset += segmentSize + (segmentSize % 2);
}

/**
 * Fill the specified vector with prime numbers up to the specified limit.
 *
 * @param primes A vector that will be filled with at least all prime numbers up
 *        to and including `limit`. If the specified vector is not empty, it
 *        must already contain the first `primes.size()` prime numbers. Note
 *        that the vector may be resized when new numbers are added, so all
 *        iterators may be invalidated.
 * @param limit The maximum prime number to be found (inclusive).
 */
void sieve_limit(std::vector<Long> &primes, Long limit) {
    // The segment size roughly corresponds to the working memory in bytes
    static constexpr std::size_t maxSegmentSize = 250'000;

    if(primes.empty()) {
        primes = {2, 3, 5, 7, 11, 13, 17, 19};
    }
    std::vector<char> mark;
    auto offset = primes.back() + 2;
    while(offset <= limit) {
        do_sieve(primes, mark, offset, limit, maxSegmentSize);
    }
}

/**
 * Create a vector with all prime numbers up to the specified limit.
 *
 * @param limit The maximum prime number to be found (inclusive).
 * @return A vector with all prime numbers up to and including `limit`.
 */
std::vector<Long> sieve(Long limit) {
    std::vector<Long> primes;
    sieve_limit(primes, limit);
    return primes;
}

/**
 * Fill the specified vector with prime numbers and return the `n`th number.
 *
 * @param primes A vector that will be filled with at least `n` prime numbers.
 *        If the specified vector is not empty, it must already contain the
 *        first `primes.size()` prime numbers. Note that the vector may be
 *        resized, so all iterators may be invalidated (this is also true when
 *        its size is greater than `n`).
 * @param n The number of prime numbers to generate (must be positive).
 * @return The `n`th prime number (2 being the 1st prime number).
 */
Long sieve(std::vector<Long> &primes, std::size_t n) {
    static constexpr std::size_t maxSegmentSize = 100'000;

    if(primes.empty()) {
        primes = {2, 3, 5, 7, 11, 13, 17, 19};
    }
    if(primes.size() >= n) {
        return primes[n - 1];
    }

    std::vector<char> mark;
    auto offset = primes.back() + 2;
    while(primes.size() < n) {
        do_sieve(primes, mark, offset, 2 * primes.back(), maxSegmentSize);
    }
    return primes[n - 1];
}
<commit_msg>Fix infinite loop in do_sieve.<commit_after>/*
 * Define functions for finding prime numbers.
 */

#include <algorithm>
#include <cmath>
#include <cstddef>
#include <vector>

using Long = unsigned long long int;

// Internal function, do not use.
void do_sieve(std::vector<Long> &primes, std::vector<char> &mark, Long &offset,
        Long limit, std::size_t maxSegmentSize) {
    auto sq = [](Long x) { return x * x; };

    std::size_t segmentSize = std::min<Long>(sq(primes.back()), limit) - offset;
    segmentSize = std::min(segmentSize, maxSegmentSize);
    if(segmentSize == 0) {
        // In case limit == offset
        // (when called from sieve_limit with limit == primes.back() + 2)
        segmentSize = 1;
    }

    mark.reserve(segmentSize);
    std::fill_n(mark.begin(), segmentSize, 1);
    for(auto it = primes.begin(); sq(*it) < offset + segmentSize; ++it) {
        // Round up to the next multiple of *it >= offset
        auto start = ((offset + *it - 1) / *it) * *it;
        for(auto idx = start - offset; idx < segmentSize; idx += *it) {
            mark[idx] = 0;
        }
    }
    for(std::size_t j = 0; j < segmentSize; j++) {
        if(mark[j]) {
            primes.push_back(offset + j);
        }
    }
    offset += segmentSize + (segmentSize % 2);
}

/**
 * Fill the specified vector with prime numbers up to the specified limit.
 *
 * @param primes A vector that will be filled with at least all prime numbers up
 *        to and including `limit`. If the specified vector is not empty, it
 *        must already contain the first `primes.size()` prime numbers. Note
 *        that the vector may be resized when new numbers are added, so all
 *        iterators may be invalidated.
 * @param limit The maximum prime number to be found (inclusive).
 */
void sieve_limit(std::vector<Long> &primes, Long limit) {
    // The segment size roughly corresponds to the working memory in bytes
    static constexpr std::size_t maxSegmentSize = 250'000;

    if(primes.empty()) {
        primes = {2, 3, 5, 7, 11, 13, 17, 19};
    }
    std::vector<char> mark;
    auto offset = primes.back() + 2;
    while(offset <= limit) {
        do_sieve(primes, mark, offset, limit, maxSegmentSize);
    }
}

/**
 * Create a vector with all prime numbers up to the specified limit.
 *
 * @param limit The maximum prime number to be found (inclusive).
 * @return A vector with all prime numbers up to and including `limit`.
 */
std::vector<Long> sieve(Long limit) {
    std::vector<Long> primes;
    sieve_limit(primes, limit);
    return primes;
}

/**
 * Fill the specified vector with prime numbers and return the `n`th number.
 *
 * @param primes A vector that will be filled with at least `n` prime numbers.
 *        If the specified vector is not empty, it must already contain the
 *        first `primes.size()` prime numbers. Note that the vector may be
 *        resized, so all iterators may be invalidated (this is also true when
 *        its size is greater than `n`).
 * @param n The number of prime numbers to generate (must be positive).
 * @return The `n`th prime number (2 being the 1st prime number).
 */
Long sieve(std::vector<Long> &primes, std::size_t n) {
    static constexpr std::size_t maxSegmentSize = 100'000;

    if(primes.empty()) {
        primes = {2, 3, 5, 7, 11, 13, 17, 19};
    }
    if(primes.size() >= n) {
        return primes[n - 1];
    }

    std::vector<char> mark;
    auto offset = primes.back() + 2;
    while(primes.size() < n) {
        do_sieve(primes, mark, offset, 2 * primes.back(), maxSegmentSize);
    }
    return primes[n - 1];
}
<|endoftext|>


<commit_before>#include <algorithm>
#include <gtest/gtest.h>
#include <autocheck/check.hpp>
#include <autocheck/sequence.hpp>

namespace ac = autocheck;

struct reverse_prop_t {
  template <typename T>
  bool operator() (const std::vector<T>& xs) const {
    std::vector<T> ys(xs);
    std::reverse(ys.begin(), ys.end());
    std::reverse(ys.begin(), ys.end());
    return xs == ys;
  }
};

template <typename T>
void insert_sorted(const T& x, std::vector<T>& xs) {
  xs.push_back(x);
  if (xs.size() == 1) return;
  for (std::vector<int>::reverse_iterator
      b = xs.rbegin(), a = b++, e = xs.rend(); (b != e) && (*a < *b); ++b, ++a)
  {
    std::iter_swap(a, b);
  }
}

template <typename T>
T copy(const T& t) { return t; }

TEST(Check, Compiles) {
  ac::gtest_reporter rep;

  ac::check<bool>(100, [] (bool x) { return true; },
      ac::make_arbitrary<bool>(), copy(rep));
  ac::check<int>(100, [] (int x) { return x >= 0; },
      ac::make_arbitrary<int>(), copy(rep));
  //ac::check<bool>(100, [] (bool x) { return true; }); // ICEs Clang

  reverse_prop_t reverse_prop;

  ac::check<std::vector<int>>(100, reverse_prop,
      ac::make_arbitrary(ac::list_of<int>()), copy(rep));
  ac::check<std::vector<int>>(100, reverse_prop,
      ac::make_arbitrary(ac::cons<std::vector<int>, unsigned int, int>()),
      copy(rep));

  ac::check<std::vector<char>>(100, reverse_prop,
      ac::make_arbitrary(ac::list_of<char>()), copy(rep));

  //std::function<bool (const std::string&)> print_prop =
    //[] (const std::string& x) { return !!(std::clog << x << std::endl); };

  //ac::check<std::string>(100, print_prop,
      //ac::make_arbitrary<std::string>(), copy(rep));
  //ac::check<std::string>(100, print_prop,
      //ac::make_arbitrary(ac::make_string_generator<ac::ccPrintable>()),
      //copy(rep));

  /* Chaining... */
  //auto arb = ac::make_arbitrary(ac::generator<int>(), ac::ordered_list<int>())
    //.only_if([] (int, const std::vector<int>& xs) -> bool { return std::is_sorted(xs.begin(), xs.end()); })
    //.at_most(100);

  /* ..., or combinators. */
  auto arb =
    ac::at_most(100,
        ac::only_if([] (int, const std::vector<int>& xs) -> bool { return std::is_sorted(xs.begin(), xs.end()); },
          ac::make_arbitrary(ac::generator<int>(), ac::ordered_list<int>())));
          //ac::make_arbitrary(ac::generator<int>(), ac::list_of<int>())));

  ac::classifier<int, std::vector<int>> cls;
  cls.trivial([] (int, const std::vector<int>& xs) { return xs.empty(); });
  cls.classify(
      [] (int x, const std::vector<int>& xs) -> std::string {
        std::ostringstream out;
        out << xs.size();
        return out.str();
      });
  cls.classify([] (int x, const std::vector<int>& xs) { return xs.empty() || (x < xs.front()); }, "at-head");
  cls.classify([] (int x, const std::vector<int>& xs) { return xs.empty() || (xs.front() < x); }, "at-tail");

  /* Can't use combinators here because it breaks template deduction (?). */
  //auto cls =
    //ac::trivial([] (int, const std::vector<int>& xs) { return xs.empty(); },
        //ac::classify(
          //[] (int x, const std::vector<int>& xs) -> std::string {
            //std::ostringstream out;
            //out << xs.size();
            //return out.str();
          //},
          //ac::classify([] (int x, const std::vector<int>& xs) { return xs.empty() || (x < xs.front()); }, "at-head",
            //ac::classify([] (int x, const std::vector<int>& xs) { return xs.empty() || (xs.back() < x); }, "at-tail",
              //ac::classifier<int, const std::vector<int>>()))));

  ac::check<int, std::vector<int>>(100,
      [] (int x, const std::vector<int>& xs) -> bool {
        std::vector<int> ys(xs);
        insert_sorted(x, ys);
        return std::is_sorted(ys.begin(), ys.end());
      },
      copy(arb), copy(rep), copy(cls));
}

<commit_msg>test strings<commit_after>#include <algorithm>
#include <gtest/gtest.h>
#include <autocheck/check.hpp>
#include <autocheck/sequence.hpp>

namespace ac = autocheck;

struct reverse_prop_t {
  template <typename T>
  bool operator() (const std::vector<T>& xs) const {
    std::vector<T> ys(xs);
    std::reverse(ys.begin(), ys.end());
    std::reverse(ys.begin(), ys.end());
    return xs == ys;
  }
};

template <typename T>
void insert_sorted(const T& x, std::vector<T>& xs) {
  xs.push_back(x);
  if (xs.size() == 1) return;
  for (std::vector<int>::reverse_iterator
      b = xs.rbegin(), a = b++, e = xs.rend(); (b != e) && (*a < *b); ++b, ++a)
  {
    std::iter_swap(a, b);
  }
}

template <typename T>
T copy(const T& t) { return t; }

TEST(Check, Compiles) {
  ac::gtest_reporter rep;

  ac::check<bool>(100, [] (bool x) { return true; },
      ac::make_arbitrary<bool>(), copy(rep));
  ac::check<int>(100, [] (int x) { return x >= 0; },
      ac::make_arbitrary<int>(), copy(rep));
  //ac::check<bool>(100, [] (bool x) { return true; }); // ICEs Clang

  reverse_prop_t reverse_prop;

  ac::check<std::vector<int>>(100, reverse_prop,
      ac::make_arbitrary(ac::list_of<int>()), copy(rep));
  ac::check<std::vector<int>>(100, reverse_prop,
      ac::make_arbitrary(ac::cons<std::vector<int>, unsigned int, int>()),
      copy(rep));

  ac::check<std::vector<char>>(100, reverse_prop,
      ac::make_arbitrary(ac::list_of<char>()), copy(rep));
  ac::check<std::vector<std::string>>(100, reverse_prop,
      ac::make_arbitrary(ac::list_of<std::string>()), copy(rep));

  //std::function<bool (const std::string&)> print_prop =
    //[] (const std::string& x) { return !!(std::clog << x << std::endl); };

  //ac::check<std::string>(100, print_prop,
      //ac::make_arbitrary<std::string>(), copy(rep));
  //ac::check<std::string>(100, print_prop,
      //ac::make_arbitrary(ac::make_string_generator<ac::ccPrintable>()),
      //copy(rep));

  /* Chaining... */
  //auto arb = ac::make_arbitrary(ac::generator<int>(), ac::ordered_list<int>())
    //.only_if([] (int, const std::vector<int>& xs) -> bool { return std::is_sorted(xs.begin(), xs.end()); })
    //.at_most(100);

  /* ..., or combinators. */
  auto arb =
    ac::at_most(100,
        ac::only_if([] (int, const std::vector<int>& xs) -> bool { return std::is_sorted(xs.begin(), xs.end()); },
          ac::make_arbitrary(ac::generator<int>(), ac::ordered_list<int>())));
          //ac::make_arbitrary(ac::generator<int>(), ac::list_of<int>())));

  ac::classifier<int, std::vector<int>> cls;
  cls.trivial([] (int, const std::vector<int>& xs) { return xs.empty(); });
  cls.classify(
      [] (int x, const std::vector<int>& xs) -> std::string {
        std::ostringstream out;
        out << xs.size();
        return out.str();
      });
  cls.classify([] (int x, const std::vector<int>& xs) { return xs.empty() || (x < xs.front()); }, "at-head");
  cls.classify([] (int x, const std::vector<int>& xs) { return xs.empty() || (xs.front() < x); }, "at-tail");

  /* Can't use combinators here because it breaks template deduction (?). */
  //auto cls =
    //ac::trivial([] (int, const std::vector<int>& xs) { return xs.empty(); },
        //ac::classify(
          //[] (int x, const std::vector<int>& xs) -> std::string {
            //std::ostringstream out;
            //out << xs.size();
            //return out.str();
          //},
          //ac::classify([] (int x, const std::vector<int>& xs) { return xs.empty() || (x < xs.front()); }, "at-head",
            //ac::classify([] (int x, const std::vector<int>& xs) { return xs.empty() || (xs.back() < x); }, "at-tail",
              //ac::classifier<int, const std::vector<int>>()))));

  ac::check<int, std::vector<int>>(100,
      [] (int x, const std::vector<int>& xs) -> bool {
        std::vector<int> ys(xs);
        insert_sorted(x, ys);
        return std::is_sorted(ys.begin(), ys.end());
      },
      copy(arb), copy(rep), copy(cls));
}

<|endoftext|>


<commit_before>#include <iostream>
#include <cstdlib>
#include <ctime>
#include <vector>

#include "termites.h"
using namespace std;

bool aleatoire(double p) {
    return rand() < p*(RAND_MAX + 1.);
}
int directionAleatoire() {
    return rand() % NB_DIRECTIONS;
}

Coord creerCoord(int i, int j) {
   Coord c;
   c.x = i;
   c.y = j;
   return c;
}
Termite creerTermite(int indice, int x, int y) {
    Termite m;
    m.coord = creerCoord(x, y);
    m.indice = indice;
    m.direction = directionAleatoire();
    m.brindille = false;
    m.tourner_sur_place = false;
    m.sablier = 0;
    return m;
}

void place_vide(Place &p) {
    p.type=PLACE_TYPE_VIDE;
    p.indtermite=-1;
}

bool contient_termite(Place &p) {
    return p.indtermite != -1;
}
bool contient_brindille(Place &p) {
    p.type = PLACE_TYPE_BRINDILLE;
    return true;
}
bool est_vide(Place &p){
return  p.type=PLACE_TYPE_VIDE;
}//verifie  par des booleens si une place est vide ou contient un termite ou une brindille

/*Coord coord_devant(Termite t){
int ind[8][2]={{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1},{1,0},{1,1}};
 creerCoord(t.coord.x+ind[t.direction,0],t.coord.y+ind[t.direction,1]);
}cette fonction genere une erreur que je vois pas du tout
c'est la fonction pr donner la nouvelle coordonnee apres deplacement.
aussi commente tes fonctions et lignes de codes particulieres et correspondances selon projet et autres
pour que je puisse comprendre plus facilement sans te deranger tout le temps
*/

void initialiseTerrain(Terrain &t) {
    t.nbtermites = 0;
    for (int y = 0; y < TAILLE; y++) {
        for (int x = 0; x < TAILLE; x++) {
            if (aleatoire(POURCENTAGE_TERMITES/100.)) {
                // aleatoire est entre 0 et 1

                Place p = t.places[y][x];
                p.type = PLACE_TYPE_TERMITE;
                p.indtermite = t.nbtermites;
                t.places[y][x] = p;

                t.termites[p.indtermite] = creerTermite(p.indtermite, x, y);
                t.nbtermites++;
            } else {
                if (aleatoire(POURCENTAGE_BRINDILLES/100)) {
                    t.places[y][x].type = PLACE_TYPE_BRINDILLE;
                } else {
                    t.places[y][x].type = PLACE_TYPE_VIDE;
                }
            }
        }
    }
}

void afficheTermite(Termite m) {
    switch (m.direction) {
        case DIRECTION_GAUCHE:
        case DIRECTION_DROITE:
            cout << "-";
            break;
        case DIRECTION_HAUT:
        case DIRECTION_BAS:
            cout << "|";
            break;
        case DIRECTION_GAUCHE_HAUT:
        case DIRECTION_DROITE_BAS:
            cout << "\\";
            break;
        case DIRECTION_GAUCHE_BAS:
        case DIRECTION_DROITE_HAUT:
            cout << "/";
            break;
        default:
            cout << "D";
    }
}
void afficheTerrain(Terrain t) {
    for(int y = 0; y < TAILLE; y++) {
        if (y) cout << endl;
        for (int x = 0; x < TAILLE; x++) {
            Place p = t.places[y][x];
            int type_place = p.type;
            switch (type_place){
                case PLACE_TYPE_VIDE:{
                    cout << "-";
                break;
                }
                case PLACE_TYPE_BRINDILLE:{
                    cout << "0";
                break;
                }
                case PLACE_TYPE_TERMITE:{
                    Termite m = t.termites[p.indtermite];
                    afficheTermite(m);
                break;
                }
                default:
                    cout << "?";
            }
        }
    }
    cout << endl << endl;
}

int main() {
    srand(time(NULL));
    cout << endl;
    Terrain t;
    initialiseTerrain(t);
    afficheTerrain(t);
    return 0;
}
<commit_msg>Add coordDevant, estVide<commit_after>#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
#include <vector>

#include "termites.h"
using namespace std;

void WTF(string str) {
    cout << "\x1B[41m \x1B[1mWTF : \x1B[2m" << str << " \x1B[0m";
};

bool aleatoire(double p) {
    return rand() < p*(RAND_MAX + 1.);
}
int directionAleatoire() {
    return rand() % NB_DIRECTIONS;
}

Coord creerCoord(int i, int j) {
   Coord c;
   c.x = i;
   c.y = j;
   return c;
}
Termite creerTermite(int indice, int x, int y) {
    Termite m;
    m.coord = creerCoord(x, y);
    m.indice = indice;
    m.direction = directionAleatoire();
    m.brindille = false;
    m.tourner_sur_place = false;
    m.sablier = 0;
    return m;
}

void placeVide(Place &p) {
    p.type = PLACE_TYPE_VIDE;
}

bool contientTermite(Place &p) {
    return p.type == PLACE_TYPE_TERMITE;
}
bool contientBrindille(Place &p) {
    return p.type == PLACE_TYPE_BRINDILLE;
}
bool estVide(Place &p) {
    return p.type == PLACE_TYPE_VIDE;
}//verifie  par des booleens si une place est vide ou contient un termite ou une brindille

Coord coordDevant(Termite t){
    if (t.direction < 0 || t.direction >= NB_DIRECTIONS) { // pas bien
        WTF("[coordDevant] Termite mutante");
        return creerCoord(-1, -1);
    }
    int ind[8][2] = {{0,-1}, {-1,1}, {1,0}, {1,1}, {0,1}, {-1,1}, {-1,0}, {-1,-1}};
    //          haut| haut_droite| droite| ba|s_droite |bas |bas_gauche |gauche |haut_gauche
    return creerCoord(t.coord.x + ind[t.direction][0], t.coord.y + ind[t.direction][1]);
}/*cette fonction genere une erreur que je vois pas du tout
c'est la fonction pr donner la nouvelle coordonnee apres deplacement.*/
// tas oublié le return gros
/*aussi commente tes fonctions et lignes de codes particulieres et correspondances selon projet et autres
pour que je puisse comprendre plus facilement sans te deranger tout le temps*/
 // ok ça marche
 // je vais mettre les commentaires des fcts dans termites.h

void initialiseTerrain(Terrain &t) {
    t.nbtermites = 0;
    for (int y = 0; y < TAILLE; y++) {
        for (int x = 0; x < TAILLE; x++) {
            if (aleatoire(POURCENTAGE_TERMITES/100.)) {
                // aleatoire est entre 0 et 1
                Place p = t.places[y][x];
                p.type = PLACE_TYPE_TERMITE;
                p.indtermite = t.nbtermites;
                t.places[y][x] = p;
                t.termites[p.indtermite] = creerTermite(p.indtermite, x, y);
                t.nbtermites++;
            } else {
                if (aleatoire(POURCENTAGE_BRINDILLES/100)) {
                    t.places[y][x].type = PLACE_TYPE_BRINDILLE;
                } else {
                    t.places[y][x].type = PLACE_TYPE_VIDE;
                }
            }
        }
    }
}

void afficheTermite(Termite m) {
    switch (m.direction) {
        case DIRECTION_GAUCHE:
        case DIRECTION_DROITE:
            cout << "-";
            break;
        case DIRECTION_HAUT:
        case DIRECTION_BAS:
            cout << "|";
            break;
        case DIRECTION_GAUCHE_HAUT:
        case DIRECTION_DROITE_BAS:
            cout << "\\";
            break;
        case DIRECTION_GAUCHE_BAS:
        case DIRECTION_DROITE_HAUT:
            cout << "/";
            break;
        default:
            cout << "D";
    }
}
void afficheTerrain(Terrain t) {
    for(int y = 0; y < TAILLE; y++) {
        if (y) cout << endl;
        for (int x = 0; x < TAILLE; x++) {
            Place p = t.places[y][x];
            int type_place = p.type;
            switch (type_place){
                case PLACE_TYPE_VIDE:{
                    cout << "-";
                break;
                }
                case PLACE_TYPE_BRINDILLE:{
                    cout << "0";
                break;
                }
                case PLACE_TYPE_TERMITE:{
                    Termite m = t.termites[p.indtermite];
                    afficheTermite(m);
                break;
                }
                default:
                    cout << "?";
            }
        }
    }
    cout << endl << endl;
}

int main() {
    srand(time(NULL));
    cout << endl;
    Terrain t;
    initialiseTerrain(t);
    afficheTerrain(t);
    return 0;
}
<|endoftext|>


<commit_before>#include <dlfcn.h>

#include "loader.h"

BVS::Loader::Loader(Control& control, const Info& info)
	: control(control),
	logger("Loader"),
	info(info),
	modules(Control::modules),
	moduleStack()
{

}

BVS::Loader& BVS::Loader::load(const std::string& moduleTraits, const bool asThread, const std::string& poolName)
{
	/* algorithm:
	 * SEPARATE id(library).options
	 * CHECK for duplicate ids
	 * LOAD the library and CHECK errors
	 * LINK and execute register function, CHECK errors
	 * SAVE metadata
	 * MOVE connectors to metadata
	 * START (un/)threaded module
	 */
	std::string id;
	std::string library;
	std::string options;

	// search for '.' in id and separate id and options
	size_t separator = moduleTraits.find_first_of('.');
	if (separator!=std::string::npos)
	{
		id = moduleTraits.substr(0, separator);
		options = moduleTraits.substr(separator+1, std::string::npos);
	}
	else
		id = moduleTraits;

	// search for '(' in id and separate if necessary
	separator = id.find_first_of('(');
	if (separator!=std::string::npos)
	{
		library = id.substr(separator+1, std::string::npos);
		library.erase(library.length()-1);
		id = id.erase(separator, std::string::npos);
	}
	else
		library = id;

	// search for duplicate id in modules
	if (modules.find(id)!=modules.end())
	{
		LOG(0, "Duplicate id for module: " << id);
		LOG(0, "If you try to load a module more than once, use unique ids and the id(library).options syntax!");
		exit(-1);
	}

	// load library
	LibHandle dlib = loadLibrary(id, library);

	// look for bvsRegisterModule in loaded lib, check for errors and execute register function
	typedef void (*bvsRegisterModule_t)(const std::string& id, const Info& info);
	bvsRegisterModule_t bvsRegisterModule;
	*reinterpret_cast<void**>(&bvsRegisterModule)=dlsym(dlib, "bvsRegisterModule");

	// check for errors
	char* dlerr = dlerror();
	if (dlerr)
	{
		LOG(0, "Loading function bvsRegisterModule() in '" << library << "' resulted in: " << dlerr);
		exit(-1);
	}

	// register
	bvsRegisterModule(id, info);
	LOG(2, "Loading '" << id << "' successfull!");

	// load library and save handle, library name and option string for later use
	modules[id]->dlib = dlib;
	modules[id]->library = library;
	modules[id]->options = options;

	// move connectors from temporary to metadata
	modules[id]->connectors = std::move(ConnectorDataCollector::connectors);

	// let control handle module start
	modules[id]->asThread = asThread;
	modules[id]->poolName = poolName;
	control.startModule(id);

	moduleStack.push(id);

	return *this;
}

BVS::Loader& BVS::Loader::unload(const std::string& id)
{
	/* algorithm:
	 * CHECK thread, signal exit
	 * DISCONNECT connectors
	 * DELETE module instance and connectors
	 * CHECK library handle
	 * PURGE module and its metadata
	 * CLOSE library
	 * CHECK errors
	 */
	// wait for thread to join, first check if it is still running
	if (modules[id]->asThread == true)
	{
		if (modules[id]->thread.joinable())
		{
			modules[id]->flag = ControlFlag::QUIT;
			control.notifyThreads();
			LOG(3, "Waiting for '" << id << "' to join!");
			modules[id]->thread.join();
		}
	}

	// disconnect connectors
	for (auto& it: modules)
	{
		for (auto& con: it.second->connectors)
		{
			if (con.second->type==ConnectorType::INPUT) continue;

			// find and reset all inputs connected to output
			for (auto& mods: modules)
			{
				for (auto& modCon: mods.second->connectors)
				{
					if (con.second->pointer==modCon.second->pointer)
					{
						modCon.second->pointer = nullptr;
						modCon.second->active = false;
						modCon.second->mutex = nullptr;
					}
				}

			}
		}
	}

	unloadLibrary(id, true);

	return *this;
}

BVS::Loader& BVS::Loader::unloadAll()
{
	while (!moduleStack.empty())
	{
		if(modules.find(moduleStack.top())!=modules.end())
		{
			unload(moduleStack.top());
		}
		moduleStack.pop();
	}

	return *this;
}

BVS::Loader& BVS::Loader::connectAllModules(const bool connectorTypeMatching)
{
	for (auto& it: modules) connectModule(it.second->id, connectorTypeMatching);

	return *this;
}

BVS::Loader& BVS::Loader::connectModule(const std::string& id, const bool connectorTypeMatching)
{
	/* algorithm:
	 * WHILE option string not empty
	 *	SEPARATE selection
	 * 	CHECK input and output
	 * 	CHECK input typeid hash == output typeid hash
	 * 	CONNECT
	 * DONE
	 */

	ModuleData* module = modules[id].get();
	std::string options = module->options;
	std::string selection;
	std::string input;
	std::string targetModule;
	std::string targetOutput;
	size_t separator;
	size_t separator2;

	while (!options.empty())
	{
		// get input name and selection
		separator = options.find_first_of('(');
		separator2 = options.find_first_of(')');
		selection = options.substr(0, separator2+1);
		if (separator!=std::string::npos)
		{
			input = options.substr(0, separator);
			targetModule= options.substr(separator+1, separator2-separator-1);
		}
		else
		{
			LOG(0, "No input selection found: " << selection);
			exit(1);
		}

		// remove parsed part
		options.erase(0, separator2+1);
		if (options[0] == '.') options.erase(options.begin());

		// search for '.' in selection and separate module and output
		separator = targetModule.find_first_of('.');
		if (separator!=std::string::npos)
		{
			targetOutput = targetModule.substr(separator+1, std::string::npos);
			targetModule = targetModule.substr(0, separator);
		}
		else
		{
			LOG(0, "No module output selected: " << module->id << "." << selection);
			exit(1);
		}

		// check input and output
		checkModuleInput(module, input);
		checkModuleOutput(module, targetModule, targetOutput);

		// check input typeid hash == output typeid hash
		if (connectorTypeMatching && module->connectors[input]->typeIDHash != modules[targetModule]->connectors[targetOutput]->typeIDHash)
		{
			LOG(0, "Selected input and output connector template instantiations are of different type: "
					<< module->id << "." << selection << " -> "
					<< module->connectors[input]->typeIDName << " != " << modules[targetModule]->connectors[targetOutput]->typeIDName);
			exit(1);
		}

		// connect
		module->connectors[input]->pointer = modules[targetModule]->connectors[targetOutput]->pointer;
		module->connectors[input]->mutex = modules[targetModule]->connectors[targetOutput]->mutex;
		LOG(3, "Connected: " << module->id << "." << module->connectors[input]->id << " <- " << modules[targetModule]->id << "." << modules[targetModule]->connectors[targetOutput]->id);
	}

	return *this;
}

BVS::Loader& BVS::Loader::hotSwapModule(const std::string& id)
{
#ifdef BVS_MODULE_HOTSWAP
	// wait for thread or pool
	if (modules[id]->asThread || !modules[id]->poolName.empty())
		control.waitUntilInactive(id);

	// reload library
	unloadLibrary(id, false);
	LibHandle dlib = loadLibrary(id, modules[id]->library);

	// look for bvsHotSwapModule
	typedef void (*bvsHotSwapModule_t)(const std::string& id, BVS::Module* module);
	bvsHotSwapModule_t bvsHotSwapModule;
	*reinterpret_cast<void**>(&bvsHotSwapModule)=dlsym(dlib, "bvsHotSwapModule");

	// check for errors
	char* dlerr = dlerror();
	if (dlerr)
	{
		LOG(0, "Loading function bvsHotSwapModule() in '" << modules[id]->library << "' resulted in: " << dlerr);
		exit(-1);
	}

	// call hotswap routine in module
	bvsHotSwapModule(id, modules[id]->module.get());
	LOG(2, "Hotswapping '" << id << "' successfull!");

	// save new dlib information
	modules[id]->dlib = dlib;
#else //BVS_MODULE_HOTSWAP
	LOG(0, "ERROR: HotSwap disabled, could not hotswap: '" << id << "'!");
#endif //BVS_MODULE_HOTSWAP

	return *this;
}

BVS::LibHandle BVS::Loader::loadLibrary(const std::string& id, const std::string& library)
{
	// prepare path and load the lib
	std::string modulePath = "lib" + library + ".so";
	LibHandle dlib = dlopen(modulePath.c_str(), RTLD_NOW);
	if (dlib!=NULL)
	{
		LOG(3, "Loading '" << id << "' from '" << modulePath << "'!");
	}
	else
	{
#ifdef BVS_OSX_ANOMALIES
		// additional check for 'dylib' (when compiled under OSX as SHARED instead of MODULE)
		modulePath.resize(modulePath.size()-2);
		modulePath += "dylib";
		dlib = dlopen(modulePath.c_str(), RTLD_NOW);
		if (dlib!=NULL) LOG(3, "Loading " << id << " from " << modulePath << "!");
#endif //BVS_OSX_ANOMALIES
	}

	// check for errors
	if (dlib==NULL)
	{
		LOG(0, "Loading '" << modulePath << "' resulted in: " << dlerror());
		exit(-1);
	}

	return dlib;
}

BVS::Loader& BVS::Loader::unloadLibrary(const std::string& id, const bool& purgeModuleData)
{
	// close lib and check for errors
#ifndef BVS_OSX_ANOMALIES
	std::string modulePath = "./lib" + modules[id]->library + ".so";
#else
	std::string modulePath = "./lib" + modules[id]->library + ".(so|dylib)";
#endif //BVS_OSX_ANOMALIES
	LOG(3, "Module '" << id << "' unloading from '" << modulePath << "'!");

	// get handle from internals
	void* dlib = modules[id]->dlib;
	if (dlib==nullptr)
	{
		LOG(0, "Requested module '" << id << "' not found!");
		exit(-1);
	}

	// purge module data if desired
	if (purgeModuleData) control.purgeData(id);

	// close the lib
	dlclose(dlib);

	// check for errors
	char* dlerr = dlerror();
	if (dlerr)
	{
		LOG(0, "While closing '" << modulePath << "' following error occured: " << dlerror());
		exit(-1);
	}
	LOG(2, "Library '" << modulePath << "' unloaded!");

	return *this;
}

BVS::Loader& BVS::Loader::checkModuleInput(const ModuleData* module, const std::string& inputName)
{
	auto input = module->connectors.find(inputName);

	// check existence and type
	if (input == module->connectors.end() || input->second->type != ConnectorType::INPUT)
	{
		LOG(0, "Input not found: " << module->id << "." << inputName);
		printModuleConnectors(module);
		exit(1);
	}

	// check if input is already connected
	if (input->second->active)
	{
		LOG(0, "Input already connected: " << module->id << "." << inputName);
		exit(1);
	}

	return *this;
}

BVS::Loader& BVS::Loader::checkModuleOutput(const ModuleData* module, const std::string& targetModule, const std::string& targetOutput)
{
	(void) module;
	auto target = modules.find(targetModule);

	// check if desired module exists
	if (target == modules.end())
	{
		LOG(0, "Module not found: " << targetModule << " in " << module->id << "." << module->options);
		exit(1);
	}

	auto output = target->second->connectors.find(targetOutput);

	// check output existence and type
	if (output == target->second->connectors.end() || output->second->type != ConnectorType::OUTPUT)
	{
		LOG(0, "Output not found: " << targetOutput << " in " << module->id << "." << module->options);
		printModuleConnectors(target->second.get());
		exit(1);
	}

	return *this;
}

BVS::Loader& BVS::Loader::printModuleConnectors(const ModuleData* module)
{
	if (module->connectors.size()==0)
	{
		LOG(0, "Module " << module->id << " does not define any connector!");
	}
	else
	{
		LOG(0, "Module " << module->id << " defines the following connectors: ");
		for (auto& it: module->connectors) LOG(0, it.second->type << ": " << it.second->id);
	}

	return *this;
}

<commit_msg>loader: cleanup and remove superficial or wrong comments<commit_after>#include <dlfcn.h>

#include "loader.h"

BVS::Loader::Loader(Control& control, const Info& info)
	: control(control),
	logger("Loader"),
	info(info),
	modules(Control::modules),
	moduleStack()
{ }

BVS::Loader& BVS::Loader::load(const std::string& moduleTraits, const bool asThread, const std::string& poolName)
{
	std::string id;
	std::string library;
	std::string options;

	// separate id, library  and options
	size_t separator = moduleTraits.find_first_of('.');
	if (separator!=std::string::npos)
	{
		id = moduleTraits.substr(0, separator);
		options = moduleTraits.substr(separator+1, std::string::npos);
	}
	else id = moduleTraits;

	separator = id.find_first_of('(');
	if (separator!=std::string::npos)
	{
		library = id.substr(separator+1, std::string::npos);
		library.erase(library.length()-1);
		id = id.erase(separator, std::string::npos);
	}
	else library = id;

	if (modules.find(id)!=modules.end())
		LOG(0, "Duplicate id for module: " << id << std::endl << "If you try to load a module more than once, use unique ids and the id(library).options syntax!");

	LibHandle dlib = loadLibrary(id, library);

	// execute bvsRegisterModule in loaded lib
	typedef void (*bvsRegisterModule_t)(const std::string& id, const Info& info);
	bvsRegisterModule_t bvsRegisterModule;
	*reinterpret_cast<void**>(&bvsRegisterModule)=dlsym(dlib, "bvsRegisterModule");

	char* dlerr = dlerror();
	if (dlerr)
	{
		LOG(0, "Loading function bvsRegisterModule() in '" << library << "' resulted in: " << dlerr);
		exit(-1);
	}

	bvsRegisterModule(id, info);

	// load library and save handle, library name and option string for later use
	modules[id]->dlib = dlib;
	modules[id]->library = library;
	modules[id]->options = options;

	// get connectors and let control handle module start
	modules[id]->connectors = std::move(ConnectorDataCollector::connectors);
	modules[id]->asThread = asThread;
	modules[id]->poolName = poolName;
	control.startModule(id);

	moduleStack.push(id);

	LOG(2, "Loading '" << id << "' successfull!");

	return *this;
}

BVS::Loader& BVS::Loader::unload(const std::string& id)
{
	if (modules[id]->asThread == true)
	{
		if (modules[id]->thread.joinable())
		{
			modules[id]->flag = ControlFlag::QUIT;
			control.notifyThreads();
			LOG(3, "Waiting for '" << id << "' to join!");
			modules[id]->thread.join();
		}
	}

	for (auto& it: modules)
	{
		for (auto& con: it.second->connectors)
		{
			if (con.second->type==ConnectorType::INPUT) continue;

			for (auto& mods: modules)
			{
				for (auto& modCon: mods.second->connectors)
				{
					if (con.second->pointer==modCon.second->pointer)
					{
						modCon.second->pointer = nullptr;
						modCon.second->active = false;
						modCon.second->mutex = nullptr;
					}
				}
			}
		}
	}

	unloadLibrary(id, true);

	return *this;
}

BVS::Loader& BVS::Loader::unloadAll()
{
	while (!moduleStack.empty())
	{
		if(modules.find(moduleStack.top())!=modules.end())
		{
			unload(moduleStack.top());
		}
		moduleStack.pop();
	}

	return *this;
}

BVS::Loader& BVS::Loader::connectAllModules(const bool connectorTypeMatching)
{
	for (auto& it: modules) connectModule(it.second->id, connectorTypeMatching);

	return *this;
}

BVS::Loader& BVS::Loader::connectModule(const std::string& id, const bool connectorTypeMatching)
{
	ModuleData* module = modules[id].get();
	std::string options = module->options;
	std::string selection;
	std::string input;
	std::string targetModule;
	std::string targetOutput;
	size_t separator;
	size_t separator2;

	while (!options.empty())
	{
		separator = options.find_first_of('(');
		separator2 = options.find_first_of(')');
		selection = options.substr(0, separator2+1);
		if (separator!=std::string::npos)
		{
			input = options.substr(0, separator);
			targetModule = options.substr(separator+1, separator2-separator-1);
		}
		else
		{
			LOG(0, "No input selection found: " << selection);
			exit(1);
		}

		options.erase(0, separator2+1);
		if (options[0] == '.') options.erase(options.begin());

		separator = targetModule.find_first_of('.');
		if (separator!=std::string::npos)
		{
			targetOutput = targetModule.substr(separator+1, std::string::npos);
			targetModule = targetModule.substr(0, separator);
		}
		else
		{
			LOG(0, "No module output selected: " << module->id << "." << selection);
			exit(1);
		}

		checkModuleInput(module, input);
		checkModuleOutput(module, targetModule, targetOutput);

		if (connectorTypeMatching && module->connectors[input]->typeIDHash != modules[targetModule]->connectors[targetOutput]->typeIDHash)
		{
			LOG(0, "Selected input and output connector template instantiations are of different type: " << module->id << "." << selection << " -> " << module->connectors[input]->typeIDName << " != " << modules[targetModule]->connectors[targetOutput]->typeIDName);
			exit(1);
		}

		module->connectors[input]->pointer = modules[targetModule]->connectors[targetOutput]->pointer;
		module->connectors[input]->mutex = modules[targetModule]->connectors[targetOutput]->mutex;
		LOG(3, "Connected: " << module->id << "." << module->connectors[input]->id << " <- " << modules[targetModule]->id << "." << modules[targetModule]->connectors[targetOutput]->id);
	}

	return *this;
}

BVS::Loader& BVS::Loader::hotSwapModule(const std::string& id)
{
#ifdef BVS_MODULE_HOTSWAP
	if (modules[id]->asThread || !modules[id]->poolName.empty()) control.waitUntilInactive(id);

	unloadLibrary(id, false);
	LibHandle dlib = loadLibrary(id, modules[id]->library);

	typedef void (*bvsHotSwapModule_t)(const std::string& id, BVS::Module* module);
	bvsHotSwapModule_t bvsHotSwapModule;
	*reinterpret_cast<void**>(&bvsHotSwapModule)=dlsym(dlib, "bvsHotSwapModule");

	char* dlerr = dlerror();
	if (dlerr)
	{
		LOG(0, "Loading function bvsHotSwapModule() in '" << modules[id]->library << "' resulted in: " << dlerr);
		exit(-1);
	}

	bvsHotSwapModule(id, modules[id]->module.get());
	modules[id]->dlib = dlib;

	LOG(2, "Hotswapping '" << id << "' successfull!");
#else //BVS_MODULE_HOTSWAP
	LOG(0, "ERROR: HotSwap disabled, could not hotswap: '" << id << "'!");
#endif //BVS_MODULE_HOTSWAP

	return *this;
}

BVS::LibHandle BVS::Loader::loadLibrary(const std::string& id, const std::string& library)
{
	std::string modulePath = "lib" + library + ".so";
	LibHandle dlib = dlopen(modulePath.c_str(), RTLD_NOW);
	if (dlib!=NULL)
	{
		LOG(3, "Loading '" << id << "' from '" << modulePath << "'!");
	}
	else
	{
#ifdef BVS_OSX_ANOMALIES
		// additional check for 'dylib' (when compiled under OSX as SHARED instead of MODULE)
		modulePath.resize(modulePath.size()-2);
		modulePath += "dylib";
		dlib = dlopen(modulePath.c_str(), RTLD_NOW);
		if (dlib!=NULL) LOG(3, "Loading " << id << " from " << modulePath << "!");
#endif //BVS_OSX_ANOMALIES
	}

	if (dlib==NULL)
	{
		LOG(0, "Loading '" << modulePath << "' resulted in: " << dlerror());
		exit(-1);
	}

	return dlib;
}

BVS::Loader& BVS::Loader::unloadLibrary(const std::string& id, const bool& purgeModuleData)
{
#ifndef BVS_OSX_ANOMALIES
	std::string modulePath = "./lib" + modules[id]->library + ".so";
#else
	std::string modulePath = "./lib" + modules[id]->library + ".(so|dylib)";
#endif //BVS_OSX_ANOMALIES
	LOG(3, "Module '" << id << "' unloading from '" << modulePath << "'!");

	void* dlib = modules[id]->dlib;
	if (dlib==nullptr)
	{
		LOG(0, "Requested module '" << id << "' not found!");
		exit(-1);
	}

	if (purgeModuleData) control.purgeData(id);
	dlclose(dlib);

	char* dlerr = dlerror();
	if (dlerr)
	{
		LOG(0, "While closing '" << modulePath << "' following error occured: " << dlerror());
		exit(-1);
	}
	LOG(2, "Library '" << modulePath << "' unloaded!");

	return *this;
}

BVS::Loader& BVS::Loader::checkModuleInput(const ModuleData* module, const std::string& inputName)
{
	auto input = module->connectors.find(inputName);

	if (input == module->connectors.end() || input->second->type != ConnectorType::INPUT)
	{
		LOG(0, "Input not found: " << module->id << "." << inputName);
		printModuleConnectors(module);
		exit(1);
	}

	if (input->second->active)
	{
		LOG(0, "Input already connected: " << module->id << "." << inputName);
		exit(1);
	}

	return *this;
}

BVS::Loader& BVS::Loader::checkModuleOutput(const ModuleData* module, const std::string& targetModule, const std::string& targetOutput)
{
	auto target = modules.find(targetModule);
	auto output = target->second->connectors.find(targetOutput);

	if (target == modules.end())
	{
		LOG(0, "Module not found: " << targetModule << " in " << module->id << "." << module->options);
		exit(1);
	}

	if (output == target->second->connectors.end() || output->second->type != ConnectorType::OUTPUT)
	{
		LOG(0, "Output not found: " << targetOutput << " in " << module->id << "." << module->options);
		printModuleConnectors(target->second.get());
		exit(1);
	}

	return *this;
}

BVS::Loader& BVS::Loader::printModuleConnectors(const ModuleData* module)
{
	if (module->connectors.size()==0)
	{
		LOG(0, "Module " << module->id << " does not define any connector!");
	}
	else
	{
		LOG(0, "Module " << module->id << " defines the following connectors: ");
		for (auto& it: module->connectors) LOG(0, it.second->type << ": " << it.second->id);
	}

	return *this;
}

<|endoftext|>