<commit_before>// Copyright (C) 2010-2013 Joshua Boyce.
// See the file COPYING for copying permission.

#pragma once

#include <cstddef>
#include <iosfwd>
#include <memory>
#include <ostream>
#include <utility>

#include <windows.h>
#include <winnt.h>

#include <hadesmem/config.hpp>
#include <hadesmem/detail/assert.hpp>
#include <hadesmem/error.hpp>
#include <hadesmem/process.hpp>
#include <hadesmem/read.hpp>

// TODO: Extra sanity checking in all components. E.g. Check
// NumberOfRvaAndSizes in NtHeaders before attempting to retrieve a data dir.

// TODO: Improve PeLib support for pathological cases like Corkami tests.

// TODO: Remove assumptions made about the format where possible. The spec is
// often wrong (or simply ignored), so we need to be permissive (but also
// defensive) if we want to be useful when dealing with hostile files.

// TODO: Full support for writing back to PE file, including automatically
// performing adjustments where required to fit in new data or remove
// unnecessary space.

// TODO: Helper functions such as FindExport, FindImport, HasDataDir,
// GetArchitecture, IsDotNet, GetPDB, etc.

// TODO: Don't crash on data which is malformed, but ignored by the PE loader
// (e.g. ISSetup.dll).

// TODO: Move PeLib code into PeLib namespace.

// TODO: Write/Set methods for PeLib should be non-const.

// TODO: Cache base pointers etc rather than retrieving it manually in every
// getter/setter.

// TODO: Rewrite PeLib to do more caching and only read/write on demand.
// Also take into account rewriting to allow writes from scratch (see other
// item) as the getters/setters obviously cant ever reference memory,
// because there might not be a memory region to reference!

// TODO: Decouple PeFile from Process. It should use a generic interface
// instead.	Another potential alternative would be policy classes. Needs
// investigation.

// TODO: Decouple PeLib from the architecture being compiled for. Required
// for cross-architecture support in hadesmem.

// TODO: Support more of the PE file format.
// Overlay data.
// Resource directory.
// Exception directory.
// Relocation directory.
// Security directory.
// Debug directory.
// Load config directory.
// Delay import directory.
// Bound import directory.
// IAT(as opposed to Import) directory.
// CLR runtime directory support.
// etc.

// TODO: Improve support for loading 'Data' files to handle pathalogical
// cases such as structures overlapping with implicitly zeroed virtual memory
// that only exists in-memory. This will probably require 'manually mapping'
// the data file. But what about files that overwrite data or overlap in
// memory but not on disk? That would potentially cause information loss...
// Keep two copies? How do we know which one to use depending on the scenario
// in that case? Needs more thought and investigation... Another concern
// would be write-back for these pathalogical files... That needs more
// thought also.

namespace hadesmem
{

// TODO: Investigate whether there is a better way to implement this.
enum class PeFileType
{
  Image,
  Data
};

class PeFile
{
public:
  explicit PeFile(Process const& process,
                  PVOID address,
                  PeFileType type,
                  DWORD size)
    : base_(static_cast<PBYTE>(address)), type_(type), size_(size)
  {
    HADESMEM_DETAIL_ASSERT(base_ != 0);
    if (type == PeFileType::Data && !size)
    {
      HADESMEM_DETAIL_THROW_EXCEPTION(Error()
                                      << ErrorString("Invalid file size."));
    }

    // Process is not actually used but we take it anyway for
    // interface symetry and in case we want to change the
    // implementation to use it later without breaking the interface.
    (void)process;
  }

  PVOID GetBase() const HADESMEM_DETAIL_NOEXCEPT
  {
    return base_;
  }

  PeFileType GetType() const HADESMEM_DETAIL_NOEXCEPT
  {
    return type_;
  }

  DWORD GetSize() const HADESMEM_DETAIL_NOEXCEPT
  {
    return size_;
  }

private:
  PBYTE base_;
  PeFileType type_;
  DWORD size_;
};

inline bool operator==(PeFile const& lhs, PeFile const& rhs)
  HADESMEM_DETAIL_NOEXCEPT
{
  return lhs.GetBase() == rhs.GetBase();
}

inline bool operator!=(PeFile const& lhs, PeFile const& rhs)
  HADESMEM_DETAIL_NOEXCEPT
{
  return !(lhs == rhs);
}

inline bool operator<(PeFile const& lhs, PeFile const& rhs)
  HADESMEM_DETAIL_NOEXCEPT
{
  return lhs.GetBase() < rhs.GetBase();
}

inline bool operator<=(PeFile const& lhs, PeFile const& rhs)
  HADESMEM_DETAIL_NOEXCEPT
{
  return lhs.GetBase() <= rhs.GetBase();
}

inline bool operator>(PeFile const& lhs, PeFile const& rhs)
  HADESMEM_DETAIL_NOEXCEPT
{
  return lhs.GetBase() > rhs.GetBase();
}

inline bool operator>=(PeFile const& lhs, PeFile const& rhs)
  HADESMEM_DETAIL_NOEXCEPT
{
  return lhs.GetBase() >= rhs.GetBase();
}

inline std::ostream& operator<<(std::ostream& lhs, PeFile const& rhs)
{
  std::locale const old = lhs.imbue(std::locale::classic());
  lhs << static_cast<void*>(rhs.GetBase());
  lhs.imbue(old);
  return lhs;
}

inline std::wostream& operator<<(std::wostream& lhs, PeFile const& rhs)
{
  std::locale const old = lhs.imbue(std::locale::classic());
  lhs << static_cast<void*>(rhs.GetBase());
  lhs.imbue(old);
  return lhs;
}

inline PVOID RvaToVa(Process const& process, PeFile const& pe_file, DWORD rva)
{
  PeFileType const type = pe_file.GetType();
  PBYTE base = static_cast<PBYTE>(pe_file.GetBase());

  if (type == PeFileType::Data)
  {
    if (!rva)
    {
      return nullptr;
    }

    IMAGE_DOS_HEADER dos_header = Read<IMAGE_DOS_HEADER>(process, base);
    if (dos_header.e_magic != IMAGE_DOS_SIGNATURE)
    {
      HADESMEM_DETAIL_THROW_EXCEPTION(Error()
                                      << ErrorString("Invalid DOS header."));
    }

    BYTE* ptr_nt_headers = base + dos_header.e_lfanew;
    IMAGE_NT_HEADERS nt_headers =
      Read<IMAGE_NT_HEADERS>(process, ptr_nt_headers);
    if (nt_headers.Signature != IMAGE_NT_SIGNATURE)
    {
      HADESMEM_DETAIL_THROW_EXCEPTION(Error()
                                      << ErrorString("Invalid NT headers."));
    }

    // Apparently on XP it's possible to load a PE with a SizeOfImage of only
    // 0x2e. Simply treat anything outside of that as invalid for now, though I
    // don't think that's entirely correct.
    // TODO: Check whether this is correct (both for the case outlined above,
    // and all other cases).
    if (rva > nt_headers.OptionalHeader.SizeOfImage)
    {
      return nullptr;
    }

    IMAGE_SECTION_HEADER* ptr_section_header =
      reinterpret_cast<PIMAGE_SECTION_HEADER>(
        ptr_nt_headers + offsetof(IMAGE_NT_HEADERS, OptionalHeader) +
        nt_headers.FileHeader.SizeOfOptionalHeader);
    IMAGE_SECTION_HEADER section_header =
      Read<IMAGE_SECTION_HEADER>(process, ptr_section_header);

    WORD num_sections = nt_headers.FileHeader.NumberOfSections;

    // Windows will load specially crafted images with no sections.
    // TODO: Check whether FileAlignment and/or SectionAlignment
    // should be checked here. In the specially crafted image I'm
    // testing this against the value is '1' for both anyway, but I'd
    // like to ensure it's not possible for it to be higher, and if
    // it is, whether it would affect the RVA resolution here.
    if (!num_sections)
    {
      return base + rva;
    }

    bool in_header = true;
    for (WORD i = 0; i < num_sections; ++i)
    {
      DWORD const virtual_beg = section_header.VirtualAddress;
      DWORD const virtual_size = section_header.Misc.VirtualSize;
      DWORD const raw_size = section_header.SizeOfRawData;
      // If VirtualSize is zero then SizeOfRawData is used.
      DWORD const virtual_end =
        virtual_beg + (virtual_size ? virtual_size : raw_size);
      if (virtual_beg <= rva && rva < virtual_end)
      {
        rva -= virtual_beg;

        // If the RVA is outside the raw data (which would put it in the
        // zero-fill of the virtual data) just return nullptr because it's
        // invalid.
        // TODO: Fix this for "legitimate" cases (a struct overlapping the
        // virtual area to get 'free' zero fill, etc.).
        if (rva > raw_size)
        {
          return nullptr;
        }

        // If PointerToRawData is less than 0x200 it is rounded
        // down to 0. Safe to mask it off unconditionally because
        // it must be a multiple of FileAlignment.
        rva += section_header.PointerToRawData & ~(0x1FFUL);

        // If the RVA now lies outside the actual file just return nullptr
        // because it's invalid.
        // TODO: Verify this is correct in all cases...
        if (rva >= pe_file.GetSize())
        {
          return nullptr;
        }

        return base + rva;
      }

      // This should be the 'normal' case. However sometimes the RVA is at a
      // lower address than any of the sections, so we want to detect this so we
      // can just treat the RVA as an offset from the module base (similar to
      // when the image is loaded).
      // TODO: Check whether this is correct for all cases. Should we perhaps
      // instead check whether any sections have a PointerToRawData that is zero
      // (or rounded down to zero)?
      if (virtual_beg <= rva)
      {
        in_header = false;
      }

      section_header =
        Read<IMAGE_SECTION_HEADER>(process, ++ptr_section_header);
    }

    if (in_header && rva < pe_file.GetSize())
    {
      return base + rva;
    }

    return nullptr;
  }
  else if (type == PeFileType::Image)
  {
    return rva ? (base + rva) : nullptr;
  }
  else
  {
    HADESMEM_DETAIL_THROW_EXCEPTION(Error()
                                    << ErrorString("Unhandled file type."));
  }
}
}
<commit_msg>* [PeFile] Fix RvaToVa for esoteric PE files with a very large SizeOfHeaders. Fixes Corkami maxsec_lowalignW7.exe (before this change we fail to get the imports because RvaToVa fails).<commit_after>// Copyright (C) 2010-2013 Joshua Boyce.
// See the file COPYING for copying permission.

#pragma once

#include <cstddef>
#include <iosfwd>
#include <memory>
#include <ostream>
#include <utility>

#include <windows.h>
#include <winnt.h>

#include <hadesmem/config.hpp>
#include <hadesmem/detail/assert.hpp>
#include <hadesmem/error.hpp>
#include <hadesmem/process.hpp>
#include <hadesmem/read.hpp>

// TODO: Extra sanity checking in all components. E.g. Check
// NumberOfRvaAndSizes in NtHeaders before attempting to retrieve a data dir.

// TODO: Improve PeLib support for pathological cases like Corkami tests.

// TODO: Remove assumptions made about the format where possible. The spec is
// often wrong (or simply ignored), so we need to be permissive (but also
// defensive) if we want to be useful when dealing with hostile files.

// TODO: Full support for writing back to PE file, including automatically
// performing adjustments where required to fit in new data or remove
// unnecessary space.

// TODO: Helper functions such as FindExport, FindImport, HasDataDir,
// GetArchitecture, IsDotNet, GetPDB, etc.

// TODO: Don't crash on data which is malformed, but ignored by the PE loader
// (e.g. ISSetup.dll).

// TODO: Move PeLib code into PeLib namespace.

// TODO: Write/Set methods for PeLib should be non-const.

// TODO: Cache base pointers etc rather than retrieving it manually in every
// getter/setter.

// TODO: Rewrite PeLib to do more caching and only read/write on demand.
// Also take into account rewriting to allow writes from scratch (see other
// item) as the getters/setters obviously cant ever reference memory,
// because there might not be a memory region to reference!

// TODO: Decouple PeFile from Process. It should use a generic interface
// instead.	Another potential alternative would be policy classes. Needs
// investigation.

// TODO: Decouple PeLib from the architecture being compiled for. Required
// for cross-architecture support in hadesmem.

// TODO: Support more of the PE file format.
// Overlay data.
// Resource directory.
// Exception directory.
// Relocation directory.
// Security directory.
// Debug directory.
// Load config directory.
// Delay import directory.
// Bound import directory.
// IAT(as opposed to Import) directory.
// CLR runtime directory support.
// etc.

// TODO: Improve support for loading 'Data' files to handle pathalogical
// cases such as structures overlapping with implicitly zeroed virtual memory
// that only exists in-memory. This will probably require 'manually mapping'
// the data file. But what about files that overwrite data or overlap in
// memory but not on disk? That would potentially cause information loss...
// Keep two copies? How do we know which one to use depending on the scenario
// in that case? Needs more thought and investigation... Another concern
// would be write-back for these pathalogical files... That needs more
// thought also.

namespace hadesmem
{

// TODO: Investigate whether there is a better way to implement this.
enum class PeFileType
{
  Image,
  Data
};

class PeFile
{
public:
  explicit PeFile(Process const& process,
                  PVOID address,
                  PeFileType type,
                  DWORD size)
    : base_(static_cast<PBYTE>(address)), type_(type), size_(size)
  {
    HADESMEM_DETAIL_ASSERT(base_ != 0);
    if (type == PeFileType::Data && !size)
    {
      HADESMEM_DETAIL_THROW_EXCEPTION(Error()
                                      << ErrorString("Invalid file size."));
    }

    // Process is not actually used but we take it anyway for
    // interface symetry and in case we want to change the
    // implementation to use it later without breaking the interface.
    (void)process;
  }

  PVOID GetBase() const HADESMEM_DETAIL_NOEXCEPT
  {
    return base_;
  }

  PeFileType GetType() const HADESMEM_DETAIL_NOEXCEPT
  {
    return type_;
  }

  DWORD GetSize() const HADESMEM_DETAIL_NOEXCEPT
  {
    return size_;
  }

private:
  PBYTE base_;
  PeFileType type_;
  DWORD size_;
};

inline bool operator==(PeFile const& lhs, PeFile const& rhs)
  HADESMEM_DETAIL_NOEXCEPT
{
  return lhs.GetBase() == rhs.GetBase();
}

inline bool operator!=(PeFile const& lhs, PeFile const& rhs)
  HADESMEM_DETAIL_NOEXCEPT
{
  return !(lhs == rhs);
}

inline bool operator<(PeFile const& lhs, PeFile const& rhs)
  HADESMEM_DETAIL_NOEXCEPT
{
  return lhs.GetBase() < rhs.GetBase();
}

inline bool operator<=(PeFile const& lhs, PeFile const& rhs)
  HADESMEM_DETAIL_NOEXCEPT
{
  return lhs.GetBase() <= rhs.GetBase();
}

inline bool operator>(PeFile const& lhs, PeFile const& rhs)
  HADESMEM_DETAIL_NOEXCEPT
{
  return lhs.GetBase() > rhs.GetBase();
}

inline bool operator>=(PeFile const& lhs, PeFile const& rhs)
  HADESMEM_DETAIL_NOEXCEPT
{
  return lhs.GetBase() >= rhs.GetBase();
}

inline std::ostream& operator<<(std::ostream& lhs, PeFile const& rhs)
{
  std::locale const old = lhs.imbue(std::locale::classic());
  lhs << static_cast<void*>(rhs.GetBase());
  lhs.imbue(old);
  return lhs;
}

inline std::wostream& operator<<(std::wostream& lhs, PeFile const& rhs)
{
  std::locale const old = lhs.imbue(std::locale::classic());
  lhs << static_cast<void*>(rhs.GetBase());
  lhs.imbue(old);
  return lhs;
}

inline PVOID RvaToVa(Process const& process, PeFile const& pe_file, DWORD rva)
{
  PeFileType const type = pe_file.GetType();
  PBYTE base = static_cast<PBYTE>(pe_file.GetBase());

  if (type == PeFileType::Data)
  {
    if (!rva)
    {
      return nullptr;
    }

    IMAGE_DOS_HEADER dos_header = Read<IMAGE_DOS_HEADER>(process, base);
    if (dos_header.e_magic != IMAGE_DOS_SIGNATURE)
    {
      HADESMEM_DETAIL_THROW_EXCEPTION(Error()
                                      << ErrorString("Invalid DOS header."));
    }

    BYTE* ptr_nt_headers = base + dos_header.e_lfanew;
    IMAGE_NT_HEADERS nt_headers =
      Read<IMAGE_NT_HEADERS>(process, ptr_nt_headers);
    if (nt_headers.Signature != IMAGE_NT_SIGNATURE)
    {
      HADESMEM_DETAIL_THROW_EXCEPTION(Error()
                                      << ErrorString("Invalid NT headers."));
    }

    // SizeOfHeaders can be arbitrarily large (including the size of the
    // entire file). In this case we simply treat all RVAs as an offset from
    // zero, rather than finding its 'true' location in a section.
    if (rva < nt_headers.OptionalHeader.SizeOfHeaders)
    {
      return base + rva;
    }

    // Apparently on XP it's possible to load a PE with a SizeOfImage of only
    // 0x2e. Simply treat anything outside of that as invalid for now, though I
    // don't think that's entirely correct.
    // TODO: Check whether this is correct (both for the case outlined above,
    // and all other cases).
    if (rva > nt_headers.OptionalHeader.SizeOfImage)
    {
      return nullptr;
    }

    IMAGE_SECTION_HEADER* ptr_section_header =
      reinterpret_cast<PIMAGE_SECTION_HEADER>(
        ptr_nt_headers + offsetof(IMAGE_NT_HEADERS, OptionalHeader) +
        nt_headers.FileHeader.SizeOfOptionalHeader);
    IMAGE_SECTION_HEADER section_header =
      Read<IMAGE_SECTION_HEADER>(process, ptr_section_header);

    WORD num_sections = nt_headers.FileHeader.NumberOfSections;

    // Windows will load specially crafted images with no sections.
    // TODO: Check whether FileAlignment and/or SectionAlignment
    // should be checked here. In the specially crafted image I'm
    // testing this against the value is '1' for both anyway, but I'd
    // like to ensure it's not possible for it to be higher, and if
    // it is, whether it would affect the RVA resolution here.
    if (!num_sections)
    {
      return base + rva;
    }

    bool in_header = true;
    for (WORD i = 0; i < num_sections; ++i)
    {
      DWORD const virtual_beg = section_header.VirtualAddress;
      DWORD const virtual_size = section_header.Misc.VirtualSize;
      DWORD const raw_size = section_header.SizeOfRawData;
      // If VirtualSize is zero then SizeOfRawData is used.
      DWORD const virtual_end =
        virtual_beg + (virtual_size ? virtual_size : raw_size);
      if (virtual_beg <= rva && rva < virtual_end)
      {
        rva -= virtual_beg;

        // If the RVA is outside the raw data (which would put it in the
        // zero-fill of the virtual data) just return nullptr because it's
        // invalid.
        // TODO: Fix this for "legitimate" cases (a struct overlapping the
        // virtual area to get 'free' zero fill, etc.).
        if (rva > raw_size)
        {
          return nullptr;
        }

        // If PointerToRawData is less than 0x200 it is rounded
        // down to 0. Safe to mask it off unconditionally because
        // it must be a multiple of FileAlignment.
        rva += section_header.PointerToRawData & ~(0x1FFUL);

        // If the RVA now lies outside the actual file just return nullptr
        // because it's invalid.
        // TODO: Verify this is correct in all cases...
        if (rva >= pe_file.GetSize())
        {
          return nullptr;
        }

        return base + rva;
      }

      // This should be the 'normal' case. However sometimes the RVA is at a
      // lower address than any of the sections, so we want to detect this so we
      // can just treat the RVA as an offset from the module base (similar to
      // when the image is loaded).
      // TODO: Check whether this is correct for all cases. Should we perhaps
      // instead check whether any sections have a PointerToRawData that is zero
      // (or rounded down to zero)?
      if (virtual_beg <= rva)
      {
        in_header = false;
      }

      section_header =
        Read<IMAGE_SECTION_HEADER>(process, ++ptr_section_header);
    }

    if (in_header && rva < pe_file.GetSize())
    {
      return base + rva;
    }

    return nullptr;
  }
  else if (type == PeFileType::Image)
  {
    return rva ? (base + rva) : nullptr;
  }
  else
  {
    HADESMEM_DETAIL_THROW_EXCEPTION(Error()
                                    << ErrorString("Unhandled file type."));
  }
}
}
<|endoftext|>


<commit_before>#include <array>
#include <future>
#include <iostream>
#include <gtest/gtest.h>
#include "net/acceptor.hpp"
#include "net/connector.hpp"

using namespace std;
using namespace net;

static mutex m;

TEST(AcceptorAndConnectorTest,runTwoThreads)
{
    int s{0};
    array<int,1000> test;
    for(auto& i : test)
        i = ++s;

    auto f1 = async(
        launch::async,
        [&test]()
        {
            acceptor ator{"localhost", "54321"};
            ostream os{ator.accept()};
            for(auto i : test)
            {
                os << i << endl;
                unique_lock<mutex> l{m};
                clog << "Acceptor:  " << i << endl;
            }
        }
    );

    auto f2 = async(
        launch::async,
        [&test]()
        {
            connector ctor{"localhost", "54321"};
            istream is{ctor.connect()};
            {
                unique_lock<mutex> l{m};
                clog << "Listening..." << endl;
            }
            for(auto i : test)
            {
                int ii;
                is >> ii;
                ASSERT_EQ(i,ii);
                unique_lock<mutex> l{m};
                clog << "Connector: " << ii << endl;
            }
        }
    );

    f1.get();
    f2.get();
}
<commit_msg>Update test_acceptor_and_connector.cpp<commit_after>#include <array>
#include <future>
#include <iostream>
#include <gtest/gtest.h>
#include "net/acceptor.hpp"
#include "net/connector.hpp"

using namespace std;
using namespace net;

static mutex m;

TEST(AcceptorAndConnectorTest,runTwoThreads)
{
    int s{0};
    array<int,1000> test;
    for(auto& i : test)
        i = ++s;

    auto f1 = async(
        launch::async,
        [&test]()
        {
            acceptor ator{"localhost", "54321"};
            {
                unique_lock<mutex> l{m};
                clog << "Accepting... " << ator.host() << '.' << ator.service() << endl;
            }
            ostream os{ator.accept()};
            for(auto i : test)
            {
                os << i << endl;
                unique_lock<mutex> l{m};
                clog << "Acceptor:  " << i << endl;
            }
        }
    );

    auto f2 = async(
        launch::async,
        [&test]()
        {
            connector ctor{"localhost", "54321"};
            {
                unique_lock<mutex> l{m};
                clog << "Connecting... " << ctor.host() << '.' << ctor.service() << endl;
            }
            istream is{ctor.connect()};
            for(auto i : test)
            {
                int ii;
                is >> ii;
                ASSERT_EQ(i,ii);
                unique_lock<mutex> l{m};
                clog << "Connector: " << ii << endl;
            }
        }
    );

    f1.get();
    f2.get();
}
<|endoftext|>


<commit_before>#include "singletons.h"
#include "notebook.h"
#include "logging.h"
#include <fstream>
#include <regex>
#include "cmake.h"
#include "filesystem.h"

#if GTKSOURCEVIEWMM_MAJOR_VERSION > 2 & GTKSOURCEVIEWMM_MINOR_VERSION > 17
#include "gtksourceview-3.0/gtksourceview/gtksourcemap.h"
#endif

#include <iostream> //TODO: remove
using namespace std; //TODO: remove

namespace sigc {
#ifndef SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE
  template <typename Functor>
  struct functor_trait<Functor, false> {
    typedef decltype (::sigc::mem_fun(std::declval<Functor&>(),
                                      &Functor::operator())) _intermediate;
    typedef typename _intermediate::result_type result_type;
    typedef Functor functor_type;
  };
#else
  SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE
#endif
}

Notebook::Notebook() : Gtk::Notebook(), last_index(-1) {
  Gsv::init();

  signal_switch_page().connect([this](Gtk::Widget* page, guint page_num) {
    last_index=-1;
  });
}

int Notebook::size() {
  return get_n_pages();
}

Source::View* Notebook::get_view(int page) {
  return source_views.at(get_index(page));
}

size_t Notebook::get_index(int page) {
  for(size_t c=0;c<hboxes.size();c++) {
    if(page_num(*hboxes.at(c))==page)
      return c;
  }
  return -1;
}

Source::View* Notebook::get_current_view() {
  return get_view(get_current_page());
}

void Notebook::open(const boost::filesystem::path &file_path) {
  JDEBUG("start");
  for(int c=0;c<size();c++) {
    if(file_path==get_view(c)->file_path) {
      set_current_page(c);
      get_current_view()->grab_focus();
      return;
    }
  }

  if(boost::filesystem::exists(file_path)) {
    std::ifstream can_read(file_path.string());
    if(!can_read) {
      Singleton::terminal->print("Error: could not open "+file_path.string()+"\n", true);
      return;
    }
    can_read.close();
  }

  auto language=Source::guess_language(file_path);
  boost::filesystem::path project_path;
  auto &directories=Singleton::directories;
  if(directories->cmake && directories->cmake->project_path!="" && file_path.generic_string().substr(0, directories->cmake->project_path.generic_string().size()+1)==directories->cmake->project_path.generic_string()+'/')
    project_path=directories->cmake->project_path;
  else {
    project_path=file_path.parent_path();
    CMake cmake(project_path);
    if(cmake.project_path!="") {
      project_path=cmake.project_path;
      Singleton::terminal->print("Project path for "+file_path.string()+" set to "+project_path.string()+"\n");
    }
  }
  if(language && (language->get_id()=="chdr" || language->get_id()=="cpphdr" || language->get_id()=="c" || language->get_id()=="cpp" || language->get_id()=="objc")) {
    if(boost::filesystem::exists(project_path.string()+"/CMakeLists.txt") && !boost::filesystem::exists(project_path.string()+"/compile_commands.json"))
      CMake::create_compile_commands(project_path);
    source_views.emplace_back(new Source::ClangView(file_path, project_path, language));
  }
  else
    source_views.emplace_back(new Source::GenericView(file_path, project_path, language));

  source_views.back()->on_update_status=[this](Source::View* view, const std::string &status) {
    if(get_current_page()!=-1 && get_current_view()==view)
      Singleton::status->set_text(status+" ");
  };
  source_views.back()->on_update_info=[this](Source::View* view, const std::string &info) {
    if(get_current_page()!=-1 && get_current_view()==view)
      Singleton::info->set_text(" "+info);
  };

  scrolled_windows.emplace_back(new Gtk::ScrolledWindow());
  hboxes.emplace_back(new Gtk::HBox());
  scrolled_windows.back()->add(*source_views.back());
  hboxes.back()->pack_start(*scrolled_windows.back());

#if GTKSOURCEVIEWMM_MAJOR_VERSION > 2 & GTKSOURCEVIEWMM_MINOR_VERSION > 17
  source_maps.emplace_back(Glib::wrap(gtk_source_map_new()));
  gtk_source_map_set_view(GTK_SOURCE_MAP(source_maps.back()->gobj()), source_views.back()->gobj());
#endif
  configure(source_views.size()-1);

  std::string title=file_path.filename().string();
  append_page(*hboxes.back(), title);

  set_tab_reorderable(*hboxes.back(), true);
  show_all_children();

  size_t last_index_tmp=-1;
  if(get_current_page()!=-1)
    last_index_tmp=get_index(get_current_page());
  set_current_page(size()-1);
  last_index=last_index_tmp;

  set_focus_child(*source_views.back());
  get_current_view()->get_buffer()->set_modified(false);
  get_current_view()->grab_focus();
  //Add star on tab label when the page is not saved:
  auto source_view=get_current_view();
  get_current_view()->get_buffer()->signal_modified_changed().connect([this, source_view]() {
    std::string title=source_view->file_path.filename().string();
    if(source_view->get_buffer()->get_modified())
      title+="*";
    int page=-1;
    for(int c=0;c<size();c++) {
      if(get_view(c)==source_view) {
        page=c;
        break;
      }
    }
    if(page!=-1)
      set_tab_label_text(*(get_nth_page(page)), title);
  });

  JDEBUG("end");
}

void Notebook::configure(int view_nr) {
#if GTKSOURCEVIEWMM_MAJOR_VERSION > 2 & GTKSOURCEVIEWMM_MINOR_VERSION > 17
  auto source_font_description=Pango::FontDescription(Singleton::config->source.font);
  auto source_map_font_desc=Pango::FontDescription(static_cast<std::string>(source_font_description.get_family())+" "+Singleton::config->source.map_font_size);
  source_maps.at(view_nr)->override_font(source_map_font_desc);
  if(Singleton::config->source.show_map) {
    if(hboxes.at(view_nr)->get_children().size()==1)
      hboxes.at(view_nr)->pack_end(*source_maps.at(view_nr), Gtk::PACK_SHRINK);
  }
  else if(hboxes.at(view_nr)->get_children().size()==2)
    hboxes.at(view_nr)->remove(*source_maps.at(view_nr));
#endif
}

bool Notebook::save(int page, bool reparse_needed) {
  JDEBUG("start");
  if(page>=size()) {
    JDEBUG("end false");
    return false;
  }
  auto view=get_view(page);
  if (view->file_path != "" && view->get_buffer()->get_modified()) {
    //strip trailing whitespaces and add trailing newline if missing
    if(Singleton::config->source.strip_trailing_whitespaces) {
      auto buffer=view->get_buffer();
      for(int line=0;line<buffer->get_line_count();line++) {
        auto iter=buffer->get_iter_at_line(line);
        auto end_iter=iter;
        while(!end_iter.ends_line())
          end_iter.forward_char();
        if(iter==end_iter)
          continue;
        iter=end_iter;
        while(!iter.starts_line() && (*iter==' ' || *iter=='\t' || iter.ends_line()))
          iter.backward_char();
        if(!iter.starts_line())
          iter.forward_char();
        if(iter==end_iter)
          continue;
        buffer->erase(iter, end_iter);
      }
      auto iter=buffer->end();
      if(!iter.starts_line())
        buffer->insert(buffer->end(), "\n");
    }

    if(filesystem::write(view->file_path, view->get_buffer())) {
      if(reparse_needed) {
        if(auto clang_view=dynamic_cast<Source::ClangView*>(view)) {
          if(clang_view->language->get_id()=="chdr" || clang_view->language->get_id()=="cpphdr") {
            for(auto a_view: source_views) {
              if(auto a_clang_view=dynamic_cast<Source::ClangView*>(a_view)) {
                  if(clang_view!=a_clang_view)
                    a_clang_view->reparse_needed=true;
              }
            }
          }
        }
      }

      view->get_buffer()->set_modified(false);

      //If CMakeLists.txt have been modified:
      boost::filesystem::path project_path;
      if(view->file_path.filename()=="CMakeLists.txt") {
        auto &directories=Singleton::directories;
        if(directories->cmake && directories->cmake->project_path!="" && view->file_path.generic_string().substr(0, directories->cmake->project_path.generic_string().size()+1)==directories->cmake->project_path.generic_string()+'/' && CMake::create_compile_commands(directories->cmake->project_path)) {
          project_path=directories->cmake->project_path;
        }
        else {
          CMake cmake(view->file_path.parent_path());
          if(cmake.project_path!="" && CMake::create_compile_commands(cmake.project_path)) {
            project_path=cmake.project_path;
          }
        }
        if(project_path!="") {
          for(auto source_view: source_views) {
            if(auto source_clang_view=dynamic_cast<Source::ClangView*>(source_view)) {
              if(project_path==source_clang_view->project_path) {
                if(source_clang_view->restart_parse())
                  Singleton::terminal->async_print("Reparsing "+source_clang_view->file_path.string()+"\n");
                else
                  Singleton::terminal->async_print("Error: failed to reparse "+source_clang_view->file_path.string()+". Please reopen the file manually.\n", true);
              }
            }
          }
        }
      }
      JDEBUG("end true");
      return true;
    }
    Singleton::terminal->print("Error: could not save file " +view->file_path.string()+"\n", true);
  }
  JDEBUG("end false");
  return false;
}

bool Notebook::save_current() {
  if(get_current_page()==-1)
    return false;
  return save(get_current_page(), true);
}

bool Notebook::close_current_page() {
  JDEBUG("start");
  if (get_current_page()!=-1) {
    if(get_current_view()->get_buffer()->get_modified()){
      if(!save_modified_dialog()) {
        JDEBUG("end false");
        return false;
      }
    }
    int page = get_current_page();
    int index=get_index(page);

    if(last_index!=static_cast<size_t>(-1)) {
      set_current_page(page_num(*hboxes.at(last_index)));
      last_index=-1;
    }
    remove_page(page);
#if GTKSOURCEVIEWMM_MAJOR_VERSION > 2 & GTKSOURCEVIEWMM_MINOR_VERSION > 17
    source_maps.erase(source_maps.begin()+index);
#endif
    auto source_view=source_views.at(index);
    if(auto source_clang_view=dynamic_cast<Source::ClangView*>(source_view))
      source_clang_view->async_delete();
    else
      delete source_view;
    source_views.erase(source_views.begin()+index);
    scrolled_windows.erase(scrolled_windows.begin()+index);
    hboxes.erase(hboxes.begin()+index);
  }
  JDEBUG("end true");
  return true;
}

boost::filesystem::path Notebook::get_current_path() {
  boost::filesystem::path current_path;

  if(get_current_page()!=-1)
    current_path=get_current_view()->project_path;
  else
    current_path=Singleton::directories->current_path;

  return current_path;
}

bool Notebook::save_modified_dialog() {
  Gtk::MessageDialog dialog((Gtk::Window&)(*get_toplevel()), "Save file!", false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO);
  dialog.set_default_response(Gtk::RESPONSE_YES);
  dialog.set_secondary_text("Do you want to save: " + get_current_view()->file_path.string()+" ?");
  int result = dialog.run();
  if(result==Gtk::RESPONSE_YES) {
    save_current();
    return true;
  }
  else if(result==Gtk::RESPONSE_NO) {
    return true;
  }
  else {
    return false;
  }
}

<commit_msg>Fixed a bug in trailing whitespace stripping.<commit_after>#include "singletons.h"
#include "notebook.h"
#include "logging.h"
#include <fstream>
#include <regex>
#include "cmake.h"
#include "filesystem.h"

#if GTKSOURCEVIEWMM_MAJOR_VERSION > 2 & GTKSOURCEVIEWMM_MINOR_VERSION > 17
#include "gtksourceview-3.0/gtksourceview/gtksourcemap.h"
#endif

#include <iostream> //TODO: remove
using namespace std; //TODO: remove

namespace sigc {
#ifndef SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE
  template <typename Functor>
  struct functor_trait<Functor, false> {
    typedef decltype (::sigc::mem_fun(std::declval<Functor&>(),
                                      &Functor::operator())) _intermediate;
    typedef typename _intermediate::result_type result_type;
    typedef Functor functor_type;
  };
#else
  SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE
#endif
}

Notebook::Notebook() : Gtk::Notebook(), last_index(-1) {
  Gsv::init();

  signal_switch_page().connect([this](Gtk::Widget* page, guint page_num) {
    last_index=-1;
  });
}

int Notebook::size() {
  return get_n_pages();
}

Source::View* Notebook::get_view(int page) {
  return source_views.at(get_index(page));
}

size_t Notebook::get_index(int page) {
  for(size_t c=0;c<hboxes.size();c++) {
    if(page_num(*hboxes.at(c))==page)
      return c;
  }
  return -1;
}

Source::View* Notebook::get_current_view() {
  return get_view(get_current_page());
}

void Notebook::open(const boost::filesystem::path &file_path) {
  JDEBUG("start");
  for(int c=0;c<size();c++) {
    if(file_path==get_view(c)->file_path) {
      set_current_page(c);
      get_current_view()->grab_focus();
      return;
    }
  }

  if(boost::filesystem::exists(file_path)) {
    std::ifstream can_read(file_path.string());
    if(!can_read) {
      Singleton::terminal->print("Error: could not open "+file_path.string()+"\n", true);
      return;
    }
    can_read.close();
  }

  auto language=Source::guess_language(file_path);
  boost::filesystem::path project_path;
  auto &directories=Singleton::directories;
  if(directories->cmake && directories->cmake->project_path!="" && file_path.generic_string().substr(0, directories->cmake->project_path.generic_string().size()+1)==directories->cmake->project_path.generic_string()+'/')
    project_path=directories->cmake->project_path;
  else {
    project_path=file_path.parent_path();
    CMake cmake(project_path);
    if(cmake.project_path!="") {
      project_path=cmake.project_path;
      Singleton::terminal->print("Project path for "+file_path.string()+" set to "+project_path.string()+"\n");
    }
  }
  if(language && (language->get_id()=="chdr" || language->get_id()=="cpphdr" || language->get_id()=="c" || language->get_id()=="cpp" || language->get_id()=="objc")) {
    if(boost::filesystem::exists(project_path.string()+"/CMakeLists.txt") && !boost::filesystem::exists(project_path.string()+"/compile_commands.json"))
      CMake::create_compile_commands(project_path);
    source_views.emplace_back(new Source::ClangView(file_path, project_path, language));
  }
  else
    source_views.emplace_back(new Source::GenericView(file_path, project_path, language));

  source_views.back()->on_update_status=[this](Source::View* view, const std::string &status) {
    if(get_current_page()!=-1 && get_current_view()==view)
      Singleton::status->set_text(status+" ");
  };
  source_views.back()->on_update_info=[this](Source::View* view, const std::string &info) {
    if(get_current_page()!=-1 && get_current_view()==view)
      Singleton::info->set_text(" "+info);
  };

  scrolled_windows.emplace_back(new Gtk::ScrolledWindow());
  hboxes.emplace_back(new Gtk::HBox());
  scrolled_windows.back()->add(*source_views.back());
  hboxes.back()->pack_start(*scrolled_windows.back());

#if GTKSOURCEVIEWMM_MAJOR_VERSION > 2 & GTKSOURCEVIEWMM_MINOR_VERSION > 17
  source_maps.emplace_back(Glib::wrap(gtk_source_map_new()));
  gtk_source_map_set_view(GTK_SOURCE_MAP(source_maps.back()->gobj()), source_views.back()->gobj());
#endif
  configure(source_views.size()-1);

  std::string title=file_path.filename().string();
  append_page(*hboxes.back(), title);

  set_tab_reorderable(*hboxes.back(), true);
  show_all_children();

  size_t last_index_tmp=-1;
  if(get_current_page()!=-1)
    last_index_tmp=get_index(get_current_page());
  set_current_page(size()-1);
  last_index=last_index_tmp;

  set_focus_child(*source_views.back());
  get_current_view()->get_buffer()->set_modified(false);
  get_current_view()->grab_focus();
  //Add star on tab label when the page is not saved:
  auto source_view=get_current_view();
  get_current_view()->get_buffer()->signal_modified_changed().connect([this, source_view]() {
    std::string title=source_view->file_path.filename().string();
    if(source_view->get_buffer()->get_modified())
      title+="*";
    int page=-1;
    for(int c=0;c<size();c++) {
      if(get_view(c)==source_view) {
        page=c;
        break;
      }
    }
    if(page!=-1)
      set_tab_label_text(*(get_nth_page(page)), title);
  });

  JDEBUG("end");
}

void Notebook::configure(int view_nr) {
#if GTKSOURCEVIEWMM_MAJOR_VERSION > 2 & GTKSOURCEVIEWMM_MINOR_VERSION > 17
  auto source_font_description=Pango::FontDescription(Singleton::config->source.font);
  auto source_map_font_desc=Pango::FontDescription(static_cast<std::string>(source_font_description.get_family())+" "+Singleton::config->source.map_font_size);
  source_maps.at(view_nr)->override_font(source_map_font_desc);
  if(Singleton::config->source.show_map) {
    if(hboxes.at(view_nr)->get_children().size()==1)
      hboxes.at(view_nr)->pack_end(*source_maps.at(view_nr), Gtk::PACK_SHRINK);
  }
  else if(hboxes.at(view_nr)->get_children().size()==2)
    hboxes.at(view_nr)->remove(*source_maps.at(view_nr));
#endif
}

bool Notebook::save(int page, bool reparse_needed) {
  JDEBUG("start");
  if(page>=size()) {
    JDEBUG("end false");
    return false;
  }
  auto view=get_view(page);
  if (view->file_path != "" && view->get_buffer()->get_modified()) {
    //strip trailing whitespaces and add trailing newline if missing
    if(Singleton::config->source.strip_trailing_whitespaces) {
      auto buffer=view->get_buffer();
      for(int line=0;line<buffer->get_line_count();line++) {
        auto iter=buffer->get_iter_at_line(line);
        auto end_iter=iter;
        while(!end_iter.ends_line())
          end_iter.forward_char();
        if(iter==end_iter)
          continue;
        iter=end_iter;
        while(!iter.starts_line() && (*iter==' ' || *iter=='\t' || iter.ends_line()))
          iter.backward_char();
        if(*iter!=' ' && *iter!='\t')
          iter.forward_char();
        if(iter==end_iter)
          continue;
        buffer->erase(iter, end_iter);
      }
      auto iter=buffer->end();
      if(!iter.starts_line())
        buffer->insert(buffer->end(), "\n");
    }

    if(filesystem::write(view->file_path, view->get_buffer())) {
      if(reparse_needed) {
        if(auto clang_view=dynamic_cast<Source::ClangView*>(view)) {
          if(clang_view->language->get_id()=="chdr" || clang_view->language->get_id()=="cpphdr") {
            for(auto a_view: source_views) {
              if(auto a_clang_view=dynamic_cast<Source::ClangView*>(a_view)) {
                  if(clang_view!=a_clang_view)
                    a_clang_view->reparse_needed=true;
              }
            }
          }
        }
      }

      view->get_buffer()->set_modified(false);

      //If CMakeLists.txt have been modified:
      boost::filesystem::path project_path;
      if(view->file_path.filename()=="CMakeLists.txt") {
        auto &directories=Singleton::directories;
        if(directories->cmake && directories->cmake->project_path!="" && view->file_path.generic_string().substr(0, directories->cmake->project_path.generic_string().size()+1)==directories->cmake->project_path.generic_string()+'/' && CMake::create_compile_commands(directories->cmake->project_path)) {
          project_path=directories->cmake->project_path;
        }
        else {
          CMake cmake(view->file_path.parent_path());
          if(cmake.project_path!="" && CMake::create_compile_commands(cmake.project_path)) {
            project_path=cmake.project_path;
          }
        }
        if(project_path!="") {
          for(auto source_view: source_views) {
            if(auto source_clang_view=dynamic_cast<Source::ClangView*>(source_view)) {
              if(project_path==source_clang_view->project_path) {
                if(source_clang_view->restart_parse())
                  Singleton::terminal->async_print("Reparsing "+source_clang_view->file_path.string()+"\n");
                else
                  Singleton::terminal->async_print("Error: failed to reparse "+source_clang_view->file_path.string()+". Please reopen the file manually.\n", true);
              }
            }
          }
        }
      }
      JDEBUG("end true");
      return true;
    }
    Singleton::terminal->print("Error: could not save file " +view->file_path.string()+"\n", true);
  }
  JDEBUG("end false");
  return false;
}

bool Notebook::save_current() {
  if(get_current_page()==-1)
    return false;
  return save(get_current_page(), true);
}

bool Notebook::close_current_page() {
  JDEBUG("start");
  if (get_current_page()!=-1) {
    if(get_current_view()->get_buffer()->get_modified()){
      if(!save_modified_dialog()) {
        JDEBUG("end false");
        return false;
      }
    }
    int page = get_current_page();
    int index=get_index(page);

    if(last_index!=static_cast<size_t>(-1)) {
      set_current_page(page_num(*hboxes.at(last_index)));
      last_index=-1;
    }
    remove_page(page);
#if GTKSOURCEVIEWMM_MAJOR_VERSION > 2 & GTKSOURCEVIEWMM_MINOR_VERSION > 17
    source_maps.erase(source_maps.begin()+index);
#endif
    auto source_view=source_views.at(index);
    if(auto source_clang_view=dynamic_cast<Source::ClangView*>(source_view))
      source_clang_view->async_delete();
    else
      delete source_view;
    source_views.erase(source_views.begin()+index);
    scrolled_windows.erase(scrolled_windows.begin()+index);
    hboxes.erase(hboxes.begin()+index);
  }
  JDEBUG("end true");
  return true;
}

boost::filesystem::path Notebook::get_current_path() {
  boost::filesystem::path current_path;

  if(get_current_page()!=-1)
    current_path=get_current_view()->project_path;
  else
    current_path=Singleton::directories->current_path;

  return current_path;
}

bool Notebook::save_modified_dialog() {
  Gtk::MessageDialog dialog((Gtk::Window&)(*get_toplevel()), "Save file!", false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO);
  dialog.set_default_response(Gtk::RESPONSE_YES);
  dialog.set_secondary_text("Do you want to save: " + get_current_view()->file_path.string()+" ?");
  int result = dialog.run();
  if(result==Gtk::RESPONSE_YES) {
    save_current();
    return true;
  }
  else if(result==Gtk::RESPONSE_NO) {
    return true;
  }
  else {
    return false;
  }
}

<|endoftext|>


<commit_before>#include <func_gpu_object_lifetime.h>
#include <static_image.h>
#include <math.h>
#include <stdio.h>
#include <HalideRuntime.h>
#include <assert.h>
#include "../common/gpu_object_lifetime.h"

extern "C" void halide_print(void *user_context, const char *str) {
    printf("%s", str);

    record_gpu_debug(str);
}

int main(int argc, char **argv) {

    // Run the whole program several times.
    for (int i = 0; i < 2; i++) {
        Image<int> output(80);

        func_gpu_object_lifetime(output);

        output.copy_to_host();
        for (int x = 0; x < output.width(); x++) {
            if (output(x) != x) {
                printf("Error! %d != %d\n", output(x), x);
                return -1;
            }
        }

        halide_release(NULL);
    }

    int ret = validate_gpu_object_lifetime(false /* allow_globals */);
    if (ret != 0) {
        return ret;
    }

    printf("Success!\n");
    return 0;
}
<commit_msg>Image destroyed before halide_release is called, allowed none for non-GPU targets.<commit_after>#include <func_gpu_object_lifetime.h>
#include <static_image.h>
#include <math.h>
#include <stdio.h>
#include <HalideRuntime.h>
#include <assert.h>
#include "../common/gpu_object_lifetime.h"

extern "C" void halide_print(void *user_context, const char *str) {
    printf("%s", str);

    record_gpu_debug(str);
}

int main(int argc, char **argv) {

    // Run the whole program several times.
    for (int i = 0; i < 2; i++) {
        {
            Image<int> output(80);

            func_gpu_object_lifetime(output);

            output.copy_to_host();
            for (int x = 0; x < output.width(); x++) {
                if (output(x) != x) {
                    printf("Error! %d != %d\n", output(x), x);
                    return -1;
                }
            }
        }

        halide_release(NULL);
    }

    int ret = validate_gpu_object_lifetime(false /* allow_globals */, true /* allow_none */);
    if (ret != 0) {
        return ret;
    }

    printf("Success!\n");
    return 0;
}
<|endoftext|>


<commit_before>#define DEBUG 1

/**
 * File    : E2.cpp
 * Author  : Kazune Takahashi
 * Created : 2/17/2019, 2:40:07 PM
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <functional>
#include <random> // auto rd = bind(uniform_int_distribution<int>(0, 9), mt19937(10101010));
#include <chrono> // std::chrono::system_clock::time_point start_time, end_time;
// start = std::chrono::system_clock::now();
// double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end_time-start_time).count();
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;

const int MAX_SIZE = 1000010;
const long long MOD = 1000000007;

long long inv[MAX_SIZE];
long long fact[MAX_SIZE];
long long factinv[MAX_SIZE];

void init()
{
  inv[1] = 1;
  for (int i = 2; i < MAX_SIZE; i++)
  {
    inv[i] = ((MOD - inv[MOD % i]) * (MOD / i)) % MOD;
  }
  fact[0] = factinv[0] = 1;
  for (int i = 1; i < MAX_SIZE; i++)
  {
    fact[i] = (i * fact[i - 1]) % MOD;
    factinv[i] = (inv[i] * factinv[i - 1]) % MOD;
  }
}

long long C(int n, int k)
{
  if (n >= 0 && k >= 0 && n - k >= 0)
  {
    return ((fact[n] * factinv[k]) % MOD * factinv[n - k]) % MOD;
  }
  return 0;
}

long long power(long long x, long long n)
{
  if (n == 0)
  {
    return 1;
  }
  else if (n % 2 == 1)
  {
    return (x * power(x, n - 1)) % MOD;
  }
  else
  {
    long long half = power(x, n / 2);
    return (half * half) % MOD;
  }
}

long long gcd(long long x, long long y)
{
  return y ? gcd(y, x % y) : x;
}

ll N, K;
ll L;

int main()
{
  init();
  cin >> N >> K;
  L = N - K;
  ll ans = 0;
  for (ll i = L; i >= 0; i--)
  {
    ll f;
    if ((L - i) % 2 == 0)
    {
      f = 1;
    }
    else
    {
      f = -1;
    }
    ll k = i * (i + 1) / 2;
    k %= MOD;
    ans += (MOD + f * (C(L, i) * power(2, k)) % MOD) % MOD;
#if DEBUG == 1
    if (L < 10)
    {
      cerr << "i = " << i << ", k = " << k << ", power(2, " << k << ") = " << power(2, k) << ", C(" << L << ", " << i << ") = " << C(L, i) << endl;
      cerr << "ans = " << ans << endl;
    }
#endif
  }
  cout << ans << endl;
}
<commit_msg>tried E2.cpp to 'E'<commit_after>#define DEBUG 1

/**
 * File    : E2.cpp
 * Author  : Kazune Takahashi
 * Created : 2/17/2019, 2:40:07 PM
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <functional>
#include <random> // auto rd = bind(uniform_int_distribution<int>(0, 9), mt19937(10101010));
#include <chrono> // std::chrono::system_clock::time_point start_time, end_time;
// start = std::chrono::system_clock::now();
// double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end_time-start_time).count();
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;

const int MAX_SIZE = 1000010;
const long long MOD = 1000000007;

long long inv[MAX_SIZE];
long long fact[MAX_SIZE];
long long factinv[MAX_SIZE];

void init()
{
  inv[1] = 1;
  for (int i = 2; i < MAX_SIZE; i++)
  {
    inv[i] = ((MOD - inv[MOD % i]) * (MOD / i)) % MOD;
  }
  fact[0] = factinv[0] = 1;
  for (int i = 1; i < MAX_SIZE; i++)
  {
    fact[i] = (i * fact[i - 1]) % MOD;
    factinv[i] = (inv[i] * factinv[i - 1]) % MOD;
  }
}

long long C(int n, int k)
{
  if (n >= 0 && k >= 0 && n - k >= 0)
  {
    return ((fact[n] * factinv[k]) % MOD * factinv[n - k]) % MOD;
  }
  return 0;
}

long long power(long long x, long long n)
{
  if (n == 0)
  {
    return 1;
  }
  else if (n % 2 == 1)
  {
    return (x * power(x, n - 1)) % MOD;
  }
  else
  {
    long long half = power(x, n / 2);
    return (half * half) % MOD;
  }
}

long long gcd(long long x, long long y)
{
  return y ? gcd(y, x % y) : x;
}

ll N, K;
ll L;

int main()
{
  init();
  cin >> N >> K;
  L = N - K;
  ll ans = 0;
  for (ll i = L; i >= 0; i--)
  {
    ll f;
    if ((L - i) % 2 == 0)
    {
      f = 1;
    }
    else
    {
      f = -1;
    }
    ll k = i * (i + 1) / 2;
    k %= MOD;
    ans += (MOD + f * (C(L, i) * power(2, k)) % MOD) % MOD;
    ans %= MOD;
#if DEBUG == 1
    if (L < 10)
    {
      cerr << "i = " << i << ", k = " << k << ", power(2, " << k << ") = " << power(2, k) << ", C(" << L << ", " << i << ") = " << C(L, i) << endl;
      cerr << "ans = " << ans << endl;
    }
#endif
  }
  cout << ans << endl;
}
<|endoftext|>


<commit_before>#include <sys/types.h>
#include <string>
#include <stdexcept>

class MultipartParser {
public:
	typedef void (*Callback)(const char *buffer, size_t start, size_t end, void *userData);

private:
	static const char CR     = 13;
	static const char LF     = 10;
	static const char SPACE  = 32;
	static const char HYPHEN = 45;
	static const char COLON  = 58;
	static const char A      = 97;
	static const char Z      = 122;
	static const size_t UNMARKED = (size_t) -1;

	enum State {
		ERROR,
		START,
		START_BOUNDARY,
		HEADER_FIELD_START,
		HEADER_FIELD,
		HEADER_VALUE_START,
		HEADER_VALUE,
		HEADER_VALUE_ALMOST_DONE,
		HEADERS_ALMOST_DONE,
		PART_DATA_START,
		PART_DATA,
		PART_END,
		END
	};

	enum Flags {
		PART_BOUNDARY = 1,
		LAST_BOUNDARY = 2
	};

	std::string boundary;
	char *lookbehind;
	size_t lookbehindSize;
	State state;
	int flags;
	size_t index;
	size_t headerFieldMark;
	size_t headerValueMark;
	size_t partDataMark;
	const char *errorReason;

	void callback(Callback cb, const char *buffer = NULL, size_t start = UNMARKED, size_t end = UNMARKED) {
		if (start != UNMARKED && start == end) {
			return;
		}
		if (cb != NULL) {
			cb(buffer, start, end, userData);
		}
	}

	void dataCallback(Callback cb, size_t &mark, const char *buffer, size_t i, size_t bufferLen, bool clear) {
		if (mark == UNMARKED) {
			return;
		}

		if (!clear) {
			callback(cb, buffer, mark, bufferLen);
			mark = 0;
		} else {
			callback(cb, buffer, mark, i);
			mark = UNMARKED;
		}
	}

	char lower(char c) const {
		return c | 0x20;
	}

	bool isBoundaryChar(char c) const {
		const char *current = boundary.c_str();
		const char *end = current + boundary.size();

		while (current < end) {
			if (*current == c) {
				return true;
			}
			current++;
		}
		return false;
	}

	bool isHeaderFieldCharacter(char c) const {
		return (c >= 'a' && c <= 'z')
			|| (c >= 'A' && c <= 'Z')
			|| c == HYPHEN;
	}

	void setError(const char *message) {
		state = ERROR;
		errorReason = message;
	}

public:
	Callback onPartBegin;
	Callback onHeaderField;
	Callback onHeaderValue;
	Callback onPartData;
	Callback onPartEnd;
	Callback onEnd;
	void *userData;

	MultipartParser() {
		lookbehind = NULL;
		reset();
	}

	MultipartParser(const std::string &boundary) {
		lookbehind = NULL;
		setBoundary(boundary);
	}

	~MultipartParser() {
		delete[] lookbehind;
	}

	void reset() {
		delete[] lookbehind;
		state = ERROR;
		lookbehind = NULL;
		lookbehindSize = 0;
		flags = 0;
		index = 0;
		headerFieldMark = UNMARKED;
		headerValueMark = UNMARKED;
		partDataMark    = UNMARKED;
		errorReason = NULL;

		onPartBegin   = NULL;
		onHeaderField = NULL;
		onHeaderValue = NULL;
		onPartData    = NULL;
		onPartEnd     = NULL;
		onEnd         = NULL;
		userData      = NULL;
	}

	void setBoundary(const std::string &boundary) {
		reset();
		this->boundary = "\r\n--" + boundary;
		lookbehind = new char[this->boundary.size() + 8];
		lookbehindSize = this->boundary.size() + 8;
		state = START;
	}

	size_t feed(const char *buffer, size_t len) {
		if (state == ERROR) {
			return 0;
		}

		State state         = this->state;
		int flags           = this->flags;
		size_t prevIndex    = this->index;
		size_t index        = this->index;
		size_t boundarySize = boundary.size();
		size_t boundaryEnd  = boundarySize - 1;
		size_t i;
		char c, cl;

		for (i = 0; i < len; i++) {
			c = buffer[i];

			switch (state) {
			case ERROR:
				return i;
			case START:
				index = 0;
				state = START_BOUNDARY;
			case START_BOUNDARY:
				if (index == boundarySize - 2) {
					if (c != CR) {
						return i;
					}
					index++;
					break;
				} else if (index - 1 == boundarySize - 2) {
					if (c != LF) {
						return i;
					}
					index = 0;
					callback(onPartBegin);
					state = HEADER_FIELD_START;
					break;
				}
				if (c != boundary[index + 2]) {
					return i;
				}
				index++;
				break;
			case HEADER_FIELD_START:
				state = HEADER_FIELD;
				headerFieldMark = i;
				if (c != CR && !isHeaderFieldCharacter(c)) {
					setError("Malformd first header name character.");
					return i;
				}
			case HEADER_FIELD:
				if (c == CR) {
					headerFieldMark = UNMARKED;
					state = HEADERS_ALMOST_DONE;
					break;
				}

				if (c == HYPHEN) {
					break;
				}

				if (c == COLON) {
					dataCallback(onHeaderField, headerFieldMark, buffer, i, len, true);
					state = HEADER_VALUE_START;
					break;
				}

				cl = lower(c);
				if (cl < A || cl > Z) {
					setError("Malformed header name.");
					return i;
				}
				break;
			case HEADER_VALUE_START:
				if (c == SPACE) {
					break;
				}

				headerValueMark = i;
				state = HEADER_VALUE;
			case HEADER_VALUE:
				if (c == CR) {
					dataCallback(onHeaderValue, headerValueMark, buffer, i, len, true);
					state = HEADER_VALUE_ALMOST_DONE;
				}
				break;
			case HEADER_VALUE_ALMOST_DONE:
				if (c != LF) {
					setError("Malformed header value: LF expected after CR");
					return i;
				}

				state = HEADER_FIELD_START;
				break;
			case HEADERS_ALMOST_DONE:
				if (c != LF) {
					setError("Malformed header ending: LF expected after CR");
					return i;
				}

				state = PART_DATA_START;
				break;
			case PART_DATA_START:
				state = PART_DATA;
				partDataMark = i;
			case PART_DATA:
				prevIndex = index;

				if (index == 0) {
					// boyer-moore derrived algorithm to safely skip non-boundary data
					while (i + boundary.size() <= len) {
						if (isBoundaryChar(buffer[i + boundaryEnd])) {
							break;
						}

						i += boundary.size();
					}
					c = buffer[i];
				}

				if (index < boundary.size()) {
					if (boundary[index] == c) {
						if (index == 0) {
							dataCallback(onPartData, partDataMark, buffer, i, len, true);
						}
						index++;
					} else {
						index = 0;
					}
				} else if (index == boundary.size()) {
					index++;
					if (c == CR) {
						// CR = part boundary
						flags |= PART_BOUNDARY;
					} else if (c == HYPHEN) {
						// HYPHEN = end boundary
						flags |= LAST_BOUNDARY;
					} else {
						index = 0;
					}
				} else if (index - 1 == boundary.size()) {
					if (flags & PART_BOUNDARY) {
						index = 0;
						if (c == LF) {
							// unset the PART_BOUNDARY flag
							flags &= ~PART_BOUNDARY;
							callback(onPartEnd);
							callback(onPartBegin);
							state = HEADER_FIELD_START;
							break;
						}
					} else if (flags & LAST_BOUNDARY) {
						if (c == HYPHEN) {
							index++;
						} else {
							index = 0;
						}
					} else {
						index = 0;
					}
				} else if (index - 2 == boundary.size()) {
					if (c == CR) {
						index++;
					} else {
						index = 0;
					}
				} else if (index - boundary.size() == 3) {
					index = 0;
					if (c == LF) {
						callback(onPartEnd);
						callback(onEnd);
						state = END;
						break;
					}
				}

				if (index > 0) {
					// when matching a possible boundary, keep a lookbehind reference
					// in case it turns out to be a false lead
					if (index - 1 >= lookbehindSize) {
						throw std::out_of_range("index overflows lookbehind buffer");
					}
					lookbehind[index - 1] = c;
				} else if (prevIndex > 0) {
					// if our boundary turned out to be rubbish, the captured lookbehind
					// belongs to partData
					callback(onPartData, lookbehind, 0, prevIndex);
					prevIndex = 0;
					partDataMark = i;
				}

				break;
			default:
				return i;
			}
		}

		dataCallback(onHeaderField, headerFieldMark, buffer, i, len, false);
		dataCallback(onHeaderValue, headerValueMark, buffer, i, len, false);
		dataCallback(onPartData, partDataMark, buffer, i, len, false);

		this->index = index;
		this->state = state;
		this->flags = flags;

		return len;
	}

	bool succeeded() const {
		return state == END;
	}

	bool hasError() const {
		return state == ERROR;
	}

	bool stopped() const {
		return state == ERROR || state == END;
	}

	const char *getErrorMessage() const {
		return errorReason;
	}
};

#include <stdio.h>
using namespace std;

static void
onPartBegin(const char *buffer, size_t start, size_t end, void *userData) {
	printf("onPartBegin\n");
}

static void
onHeaderField(const char *buffer, size_t start, size_t end, void *userData) {
	printf("onHeaderField: (%s)\n", string(buffer + start, end - start).c_str());
}

static void
onHeaderValue(const char *buffer, size_t start, size_t end, void *userData) {
	printf("onHeaderValue: (%s)\n", string(buffer + start, end - start).c_str());
}

static void
onPartData(const char *buffer, size_t start, size_t end, void *userData) {
	printf("onPartData: (%s)\n", string(buffer + start, end - start).c_str());
}

static void
onPartEnd(const char *buffer, size_t start, size_t end, void *userData) {
	printf("onPartEnd\n");
}

static void
onEnd(const char *buffer, size_t start, size_t end, void *userData) {
	printf("onEnd\n");
}

int
main() {
	MultipartParser parser("abcd");
	parser.onPartBegin = onPartBegin;
	parser.onHeaderField = onHeaderField;
	parser.onHeaderValue = onHeaderValue;
	parser.onPartData = onPartData;
	parser.onPartEnd = onPartEnd;
	parser.onEnd = onEnd;

	while (!parser.stopped() && !feof(stdin)) {
		char buf[5];
		size_t len = fread(buf, 1, sizeof(buf), stdin);
		size_t fed = 0;
		do {
			size_t ret = parser.feed(buf + fed, len - fed);
			fed += ret;
			printf("accepted %d bytes\n", (int) ret);
		} while (fed < len && !parser.stopped());
	}
	printf("%s\n", parser.getErrorMessage());
	return 0;
}
<commit_msg>Allow empty header values.<commit_after>#include <sys/types.h>
#include <string>
#include <stdexcept>

class MultipartParser {
public:
	typedef void (*Callback)(const char *buffer, size_t start, size_t end, void *userData);

private:
	static const char CR     = 13;
	static const char LF     = 10;
	static const char SPACE  = 32;
	static const char HYPHEN = 45;
	static const char COLON  = 58;
	static const char A      = 97;
	static const char Z      = 122;
	static const size_t UNMARKED = (size_t) -1;

	enum State {
		ERROR,
		START,
		START_BOUNDARY,
		HEADER_FIELD_START,
		HEADER_FIELD,
		HEADER_VALUE_START,
		HEADER_VALUE,
		HEADER_VALUE_ALMOST_DONE,
		HEADERS_ALMOST_DONE,
		PART_DATA_START,
		PART_DATA,
		PART_END,
		END
	};

	enum Flags {
		PART_BOUNDARY = 1,
		LAST_BOUNDARY = 2
	};

	std::string boundary;
	char *lookbehind;
	size_t lookbehindSize;
	State state;
	int flags;
	size_t index;
	size_t headerFieldMark;
	size_t headerValueMark;
	size_t partDataMark;
	const char *errorReason;

	void callback(Callback cb, const char *buffer = NULL, size_t start = UNMARKED,
		size_t end = UNMARKED, bool allowEmpty = false)
	{
		if (start != UNMARKED && start == end && !allowEmpty) {
			return;
		}
		if (cb != NULL) {
			cb(buffer, start, end, userData);
		}
	}

	void dataCallback(Callback cb, size_t &mark, const char *buffer, size_t i, size_t bufferLen,
		bool clear, bool allowEmpty = false)
	{
		if (mark == UNMARKED) {
			return;
		}

		if (!clear) {
			callback(cb, buffer, mark, bufferLen, allowEmpty);
			mark = 0;
		} else {
			callback(cb, buffer, mark, i, allowEmpty);
			mark = UNMARKED;
		}
	}

	char lower(char c) const {
		return c | 0x20;
	}

	bool isBoundaryChar(char c) const {
		const char *current = boundary.c_str();
		const char *end = current + boundary.size();

		while (current < end) {
			if (*current == c) {
				return true;
			}
			current++;
		}
		return false;
	}

	bool isHeaderFieldCharacter(char c) const {
		return (c >= 'a' && c <= 'z')
			|| (c >= 'A' && c <= 'Z')
			|| c == HYPHEN;
	}

	void setError(const char *message) {
		state = ERROR;
		errorReason = message;
	}

public:
	Callback onPartBegin;
	Callback onHeaderField;
	Callback onHeaderValue;
	Callback onPartData;
	Callback onPartEnd;
	Callback onEnd;
	void *userData;

	MultipartParser() {
		lookbehind = NULL;
		reset();
	}

	MultipartParser(const std::string &boundary) {
		lookbehind = NULL;
		setBoundary(boundary);
	}

	~MultipartParser() {
		delete[] lookbehind;
	}

	void reset() {
		delete[] lookbehind;
		state = ERROR;
		lookbehind = NULL;
		lookbehindSize = 0;
		flags = 0;
		index = 0;
		headerFieldMark = UNMARKED;
		headerValueMark = UNMARKED;
		partDataMark    = UNMARKED;
		errorReason = NULL;

		onPartBegin   = NULL;
		onHeaderField = NULL;
		onHeaderValue = NULL;
		onPartData    = NULL;
		onPartEnd     = NULL;
		onEnd         = NULL;
		userData      = NULL;
	}

	void setBoundary(const std::string &boundary) {
		reset();
		this->boundary = "\r\n--" + boundary;
		lookbehind = new char[this->boundary.size() + 8];
		lookbehindSize = this->boundary.size() + 8;
		state = START;
	}

	size_t feed(const char *buffer, size_t len) {
		if (state == ERROR) {
			return 0;
		}

		State state         = this->state;
		int flags           = this->flags;
		size_t prevIndex    = this->index;
		size_t index        = this->index;
		size_t boundarySize = boundary.size();
		size_t boundaryEnd  = boundarySize - 1;
		size_t i;
		char c, cl;

		for (i = 0; i < len; i++) {
			c = buffer[i];

			switch (state) {
			case ERROR:
				return i;
			case START:
				index = 0;
				state = START_BOUNDARY;
			case START_BOUNDARY:
				if (index == boundarySize - 2) {
					if (c != CR) {
						return i;
					}
					index++;
					break;
				} else if (index - 1 == boundarySize - 2) {
					if (c != LF) {
						return i;
					}
					index = 0;
					callback(onPartBegin);
					state = HEADER_FIELD_START;
					break;
				}
				if (c != boundary[index + 2]) {
					return i;
				}
				index++;
				break;
			case HEADER_FIELD_START:
				state = HEADER_FIELD;
				headerFieldMark = i;
				if (c != CR && !isHeaderFieldCharacter(c)) {
					setError("Malformd first header name character.");
					return i;
				}
			case HEADER_FIELD:
				if (c == CR) {
					headerFieldMark = UNMARKED;
					state = HEADERS_ALMOST_DONE;
					break;
				}

				if (c == HYPHEN) {
					break;
				}

				if (c == COLON) {
					dataCallback(onHeaderField, headerFieldMark, buffer, i, len, true);
					state = HEADER_VALUE_START;
					break;
				}

				cl = lower(c);
				if (cl < A || cl > Z) {
					setError("Malformed header name.");
					return i;
				}
				break;
			case HEADER_VALUE_START:
				if (c == SPACE) {
					break;
				}

				headerValueMark = i;
				state = HEADER_VALUE;
			case HEADER_VALUE:
				if (c == CR) {
					dataCallback(onHeaderValue, headerValueMark, buffer, i, len, true, true);
					state = HEADER_VALUE_ALMOST_DONE;
				}
				break;
			case HEADER_VALUE_ALMOST_DONE:
				if (c != LF) {
					setError("Malformed header value: LF expected after CR");
					return i;
				}

				state = HEADER_FIELD_START;
				break;
			case HEADERS_ALMOST_DONE:
				if (c != LF) {
					setError("Malformed header ending: LF expected after CR");
					return i;
				}

				state = PART_DATA_START;
				break;
			case PART_DATA_START:
				state = PART_DATA;
				partDataMark = i;
			case PART_DATA:
				prevIndex = index;

				if (index == 0) {
					// boyer-moore derrived algorithm to safely skip non-boundary data
					while (i + boundary.size() <= len) {
						if (isBoundaryChar(buffer[i + boundaryEnd])) {
							break;
						}

						i += boundary.size();
					}
					c = buffer[i];
				}

				if (index < boundary.size()) {
					if (boundary[index] == c) {
						if (index == 0) {
							dataCallback(onPartData, partDataMark, buffer, i, len, true);
						}
						index++;
					} else {
						index = 0;
					}
				} else if (index == boundary.size()) {
					index++;
					if (c == CR) {
						// CR = part boundary
						flags |= PART_BOUNDARY;
					} else if (c == HYPHEN) {
						// HYPHEN = end boundary
						flags |= LAST_BOUNDARY;
					} else {
						index = 0;
					}
				} else if (index - 1 == boundary.size()) {
					if (flags & PART_BOUNDARY) {
						index = 0;
						if (c == LF) {
							// unset the PART_BOUNDARY flag
							flags &= ~PART_BOUNDARY;
							callback(onPartEnd);
							callback(onPartBegin);
							state = HEADER_FIELD_START;
							break;
						}
					} else if (flags & LAST_BOUNDARY) {
						if (c == HYPHEN) {
							index++;
						} else {
							index = 0;
						}
					} else {
						index = 0;
					}
				} else if (index - 2 == boundary.size()) {
					if (c == CR) {
						index++;
					} else {
						index = 0;
					}
				} else if (index - boundary.size() == 3) {
					index = 0;
					if (c == LF) {
						callback(onPartEnd);
						callback(onEnd);
						state = END;
						break;
					}
				}

				if (index > 0) {
					// when matching a possible boundary, keep a lookbehind reference
					// in case it turns out to be a false lead
					if (index - 1 >= lookbehindSize) {
						throw std::out_of_range("index overflows lookbehind buffer");
					}
					lookbehind[index - 1] = c;
				} else if (prevIndex > 0) {
					// if our boundary turned out to be rubbish, the captured lookbehind
					// belongs to partData
					callback(onPartData, lookbehind, 0, prevIndex);
					prevIndex = 0;
					partDataMark = i;
				}

				break;
			default:
				return i;
			}
		}

		dataCallback(onHeaderField, headerFieldMark, buffer, i, len, false);
		dataCallback(onHeaderValue, headerValueMark, buffer, i, len, false);
		dataCallback(onPartData, partDataMark, buffer, i, len, false);

		this->index = index;
		this->state = state;
		this->flags = flags;

		return len;
	}

	bool succeeded() const {
		return state == END;
	}

	bool hasError() const {
		return state == ERROR;
	}

	bool stopped() const {
		return state == ERROR || state == END;
	}

	const char *getErrorMessage() const {
		return errorReason;
	}
};

#include <stdio.h>
using namespace std;

static void
onPartBegin(const char *buffer, size_t start, size_t end, void *userData) {
	printf("onPartBegin\n");
}

static void
onHeaderField(const char *buffer, size_t start, size_t end, void *userData) {
	printf("onHeaderField: (%s)\n", string(buffer + start, end - start).c_str());
}

static void
onHeaderValue(const char *buffer, size_t start, size_t end, void *userData) {
	printf("onHeaderValue: (%s)\n", string(buffer + start, end - start).c_str());
}

static void
onPartData(const char *buffer, size_t start, size_t end, void *userData) {
	printf("onPartData: (%s)\n", string(buffer + start, end - start).c_str());
}

static void
onPartEnd(const char *buffer, size_t start, size_t end, void *userData) {
	printf("onPartEnd\n");
}

static void
onEnd(const char *buffer, size_t start, size_t end, void *userData) {
	printf("onEnd\n");
}

int
main() {
	MultipartParser parser("abcd");
	parser.onPartBegin = onPartBegin;
	parser.onHeaderField = onHeaderField;
	parser.onHeaderValue = onHeaderValue;
	parser.onPartData = onPartData;
	parser.onPartEnd = onPartEnd;
	parser.onEnd = onEnd;

	while (!parser.stopped() && !feof(stdin)) {
		char buf[5];
		size_t len = fread(buf, 1, sizeof(buf), stdin);
		size_t fed = 0;
		do {
			size_t ret = parser.feed(buf + fed, len - fed);
			fed += ret;
			printf("accepted %d bytes\n", (int) ret);
		} while (fed < len && !parser.stopped());
	}
	printf("%s\n", parser.getErrorMessage());
	return 0;
}
<|endoftext|>


<commit_before>#include "main_state.hpp"

#include "functions_pathing.hpp"

#include "component_drawable.hpp"
#include "component_position.hpp"
#include "component_path.hpp"
#include "component_player.hpp"
#include "component_moving.hpp"
#include "component_fire.hpp"
#include "component_ring.hpp"
#include "component_velocity.hpp"
#include "component_light.hpp"
#include "system_collision.hpp"
#include "system_controls.hpp"
#include "system_draw.hpp"
#include "system_movement.hpp"
#include "system_path.hpp"
#include "system_highscore.hpp"
#include "system_emitter.hpp"
#include "system_orbspawn.hpp"
#include "system_runes.hpp"

#include "entityx/entityx.h"
#include <glm/vec2.hpp>

#include <SDL.h>

#ifdef __EMSCRIPTEN__
#include <SDL/SDL_mixer.h>
#else
#include <SDL_mixer.h>
#endif

#include <glm/gtc/constants.hpp>

MainState::MainState(Game *game) : m_game(game) {
}

MainState::~MainState() {
}

int MainState::init() {

    m_systems.add<DrawSystem>(m_game);
    m_systems.add<ControlSystem>();
    m_systems.add<CollisionSystem>();
    m_systems.add<PathSystem>();
    m_systems.add<MovementSystem>(RING_INNER, RING_OUTER);
    m_systems.add<HighscoreSystem>(m_game);
    m_systems.add<EmitterSystem>(m_game);
    m_systems.add<RunesSystem>();
    m_systems.add<OrbSpawnSystem>(m_game, m_entities, RING_INNER, RING_OUTER);
    //
    //     // glm::vec2 origin = glm::vec2(300, 0);
    //     // auto parable = create_parable(origin, glm::vec2(300, glm::half_pi<float>()), glm::vec2(glm::one_over_root_two<float>()*300, glm::quarter_pi<float>()));
    //
    //     // glm::vec2 origin = glm::vec2(150, 0);
    //     // auto parable = create_parable(origin, glm::vec2(300, glm::half_pi<float>()), glm::vec2(150, glm::pi<float>()));
    //     //
    //     // m_systems.add<EmitterSystem>(m_game, parable, origin, 1, 10, 0.3);
    //     m_systems.add<EmitterSystem>(m_game, linear_path, 0.5, 0.3);

    m_systems.configure();

    float hp;
    switch(m_game->difficulty()) {
        default:
        case EASY:
            hp = 10;
            break;
        case MEDIUM:
            hp = 5;
            break;
        case HARD:
            hp = 3;
            break;
        case SVENSTARO:
            hp = 0;
            break;
    }

    entityx::Entity player = m_entities.create();
    // must be at (r, 3/2pi) !!
    player.assign<Position>(
            glm::vec2((RING_OUTER - RING_INNER) / 2.0 + RING_INNER, 1.5 * glm::pi<double>()));
    player.assign<Velocity>();
    player.assign<Collidable>(15);
    player.assign<Drawable>("player", 50, 30, 10, AnimTemplate(15, 25, 4, 0, 6));
    player.assign<Player>(hp);
    player.assign<Light>("gradient");

    entityx::Entity background = m_entities.create();
    background.assign<Position>(glm::vec2(0.f, 0.f));
    background.assign<Drawable>("wood", 1000, 1000, 0);

    entityx::Entity outer_bound = m_entities.create();
    outer_bound.assign<Position>(glm::vec2(0.f, 0.f));
    outer_bound.assign<Ring>();
    // for the outer bound we need additional 50 radius,
    // so that the player is inside the circle.
    outer_bound.assign<Drawable>("outer_bound", 2 * (int)RING_OUTER + 100,
            2 * (int)RING_OUTER + 100, 2);

    AnimTemplate fire_anim(32, 32, 6, 0, 10);
    entityx::Entity fire = m_entities.create();
    fire.assign<Position>(glm::vec2(0.f, 0.f));
    fire.assign<Drawable>("fire", 100, 100, 1, fire_anim);
    fire.assign<Light>("gradient");
    fire.assign<Fire>();

    Mix_VolumeMusic(50);
    Mix_PlayMusic(m_game->res_manager().music("music1"), -1);

    return 0;
}

void MainState::update(double dt) {
    SDL_Event e;
    while (SDL_PollEvent(&e)) {
        if (e.type == SDL_QUIT) {
            m_game->shutdown();
        }
        if (e.type == SDL_KEYDOWN) {
            if (e.key.keysym.sym == SDLK_ESCAPE) {
                m_game->shutdown();
            } else if (e.key.keysym.sym == SDLK_F3) {
                m_game->toggle_debug_mode();
            }
        }
    }

    m_systems.update<DrawSystem>(dt);
    m_systems.update<ControlSystem>(dt);
    m_systems.update<CollisionSystem>(dt);
    m_systems.update<MovementSystem>(dt);
    m_systems.update<HighscoreSystem>(dt);
    m_systems.update<OrbSpawnSystem>(dt);
    m_systems.update<PathSystem>(dt);
    m_systems.update<EmitterSystem>(dt);
    m_systems.update<RunesSystem>(dt);
}
<commit_msg>Smaller player<commit_after>#include "main_state.hpp"

#include "functions_pathing.hpp"

#include "component_drawable.hpp"
#include "component_position.hpp"
#include "component_path.hpp"
#include "component_player.hpp"
#include "component_moving.hpp"
#include "component_fire.hpp"
#include "component_ring.hpp"
#include "component_velocity.hpp"
#include "component_light.hpp"
#include "system_collision.hpp"
#include "system_controls.hpp"
#include "system_draw.hpp"
#include "system_movement.hpp"
#include "system_path.hpp"
#include "system_highscore.hpp"
#include "system_emitter.hpp"
#include "system_orbspawn.hpp"
#include "system_runes.hpp"

#include "entityx/entityx.h"
#include <glm/vec2.hpp>

#include <SDL.h>

#ifdef __EMSCRIPTEN__
#include <SDL/SDL_mixer.h>
#else
#include <SDL_mixer.h>
#endif

#include <glm/gtc/constants.hpp>

MainState::MainState(Game *game) : m_game(game) {
}

MainState::~MainState() {
}

int MainState::init() {

    m_systems.add<DrawSystem>(m_game);
    m_systems.add<ControlSystem>();
    m_systems.add<CollisionSystem>();
    m_systems.add<PathSystem>();
    m_systems.add<MovementSystem>(RING_INNER, RING_OUTER);
    m_systems.add<HighscoreSystem>(m_game);
    m_systems.add<EmitterSystem>(m_game);
    m_systems.add<RunesSystem>();
    m_systems.add<OrbSpawnSystem>(m_game, m_entities, RING_INNER, RING_OUTER);
    //
    //     // glm::vec2 origin = glm::vec2(300, 0);
    //     // auto parable = create_parable(origin, glm::vec2(300, glm::half_pi<float>()), glm::vec2(glm::one_over_root_two<float>()*300, glm::quarter_pi<float>()));
    //
    //     // glm::vec2 origin = glm::vec2(150, 0);
    //     // auto parable = create_parable(origin, glm::vec2(300, glm::half_pi<float>()), glm::vec2(150, glm::pi<float>()));
    //     //
    //     // m_systems.add<EmitterSystem>(m_game, parable, origin, 1, 10, 0.3);
    //     m_systems.add<EmitterSystem>(m_game, linear_path, 0.5, 0.3);

    m_systems.configure();

    float hp;
    switch(m_game->difficulty()) {
        default:
        case EASY:
            hp = 10;
            break;
        case MEDIUM:
            hp = 5;
            break;
        case HARD:
            hp = 3;
            break;
        case SVENSTARO:
            hp = 0;
            break;
    }

    entityx::Entity player = m_entities.create();
    // must be at (r, 3/2pi) !!
    player.assign<Position>(
            glm::vec2((RING_OUTER - RING_INNER) / 2.0 + RING_INNER, 1.5 * glm::pi<double>()));
    player.assign<Velocity>();
    player.assign<Collidable>(5.f);
    player.assign<Drawable>("player", 50, 30, 10, AnimTemplate(15, 25, 4, 0, 6));
    player.assign<Player>(hp);
    player.assign<Light>("gradient");

    entityx::Entity background = m_entities.create();
    background.assign<Position>(glm::vec2(0.f, 0.f));
    background.assign<Drawable>("wood", 1000, 1000, 0);

    entityx::Entity outer_bound = m_entities.create();
    outer_bound.assign<Position>(glm::vec2(0.f, 0.f));
    outer_bound.assign<Ring>();
    // for the outer bound we need additional 50 radius,
    // so that the player is inside the circle.
    outer_bound.assign<Drawable>("outer_bound", 2 * (int)RING_OUTER + 100,
            2 * (int)RING_OUTER + 100, 2);

    AnimTemplate fire_anim(32, 32, 6, 0, 10);
    entityx::Entity fire = m_entities.create();
    fire.assign<Position>(glm::vec2(0.f, 0.f));
    fire.assign<Drawable>("fire", 100, 100, 1, fire_anim);
    fire.assign<Light>("gradient");
    fire.assign<Fire>();

    Mix_VolumeMusic(50);
    Mix_PlayMusic(m_game->res_manager().music("music1"), -1);

    return 0;
}

void MainState::update(double dt) {
    SDL_Event e;
    while (SDL_PollEvent(&e)) {
        if (e.type == SDL_QUIT) {
            m_game->shutdown();
        }
        if (e.type == SDL_KEYDOWN) {
            if (e.key.keysym.sym == SDLK_ESCAPE) {
                m_game->shutdown();
            } else if (e.key.keysym.sym == SDLK_F3) {
                m_game->toggle_debug_mode();
            }
        }
    }

    m_systems.update<DrawSystem>(dt);
    m_systems.update<ControlSystem>(dt);
    m_systems.update<CollisionSystem>(dt);
    m_systems.update<MovementSystem>(dt);
    m_systems.update<HighscoreSystem>(dt);
    m_systems.update<OrbSpawnSystem>(dt);
    m_systems.update<PathSystem>(dt);
    m_systems.update<EmitterSystem>(dt);
    m_systems.update<RunesSystem>(dt);
}
<|endoftext|>


<commit_before>#include "headers/mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow) {
    ui->setupUi(this);

    /***************************************************************************
     * Create and set the settings button on the top left of the tabs
     **************************************************************************/
    buttonSettings = new QPushButton();
    ui->tabWidget->setCornerWidget(buttonSettings, Qt::TopLeftCorner);
    setupMenu();
    connect(buttonSettings, SIGNAL(clicked()),
            this, SLOT(openMenu()));

}

MainWindow::~MainWindow() {
    delete ui;
}

void MainWindow::setupMenu() {
    menuSettings = new QMenu(this);
    menuSettings->addAction("&File");
    menuSettings->addAction("&Help");

    QAction* aSettings = menuSettings->addAction("&Settings");
    connect(aSettings, SIGNAL(triggered()),
            this, SLOT(openSettings()));
    menuSettings->addSeparator();

    // Quit action
    QAction* aQuit = menuSettings->addAction("&Quit");
    this->addAction(aQuit);
    aQuit->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q));
    connect(aQuit, SIGNAL(triggered()),
            this, SLOT(close()));
}

void MainWindow::openMenu() {
    menuSettings->exec(buttonSettings->mapToGlobal(QPoint(0, buttonSettings->height())));
}

void MainWindow::openSettings() {
    OptionsWindow* settings =  new OptionsWindow(this);
    settings->show();
}
<commit_msg>Set TopLeft button text as QtChronos<commit_after>#include "headers/mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow) {
    ui->setupUi(this);

    /***************************************************************************
     * Create and set the settings button on the top left of the tabs
     **************************************************************************/
    buttonSettings = new QPushButton();
    buttonSettings->setText(QString("QtChronos"));
    ui->tabWidget->setCornerWidget(buttonSettings, Qt::TopLeftCorner);
    setupMenu();
    connect(buttonSettings, SIGNAL(clicked()),
            this, SLOT(openMenu()));

}

MainWindow::~MainWindow() {
    delete ui;
}

void MainWindow::setupMenu() {
    menuSettings = new QMenu(this);
    menuSettings->addAction("&File");
    menuSettings->addAction("&Help");

    QAction* aSettings = menuSettings->addAction("&Settings");
    connect(aSettings, SIGNAL(triggered()),
            this, SLOT(openSettings()));
    menuSettings->addSeparator();

    // Quit action
    QAction* aQuit = menuSettings->addAction("&Quit");
    this->addAction(aQuit);
    aQuit->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q));
    connect(aQuit, SIGNAL(triggered()),
            this, SLOT(close()));
}

void MainWindow::openMenu() {
    menuSettings->exec(buttonSettings->mapToGlobal(QPoint(0, buttonSettings->height())));
}

void MainWindow::openSettings() {
    OptionsWindow* settings =  new OptionsWindow(this);
    settings->show();
}
<|endoftext|>


<commit_before>#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "InstrumentPanel.h"
#include "DevicePanel.h"

// ------------------------------------------------------------------------------------------------
MainWindow::MainWindow(QWidget *parent)
	: QMainWindow(parent)
	, ui(new Ui::MainWindow)
{
	ui->setupUi(this);

	QList<QWidget*> widgets;

	auto *devicePanel = new DevicePanel();
	widgets.append(devicePanel);
	ui->tabWidget->addTab(devicePanel, tr("Devices"));

	auto *instrumentPanel = new InstrumentPanel();
	widgets.append(instrumentPanel);
	ui->tabWidget->addTab(instrumentPanel, tr("Instruments"));

	for (QWidget *& widget: widgets)
	{
		if (widget == devicePanel) continue;

		connect(devicePanel, SIGNAL(inputChanged(MIDIInput*)), widget, SLOT(setInputDevice(MIDIInput*)));
		connect(devicePanel, SIGNAL(outputChanged(MIDIOutput*)), widget, SLOT(setOutputDevice(MIDIOutput*)));
	}
}

// ------------------------------------------------------------------------------------------------
MainWindow::~MainWindow()
{
	delete ui;
}
<commit_msg>less silly collecting of main window tabs<commit_after>#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "InstrumentPanel.h"
#include "DevicePanel.h"

// ------------------------------------------------------------------------------------------------
MainWindow::MainWindow(QWidget *parent)
	: QMainWindow(parent)
	, ui(new Ui::MainWindow)
{
	ui->setupUi(this);

	QList<QWidget*> widgets;

	auto *devicePanel = new DevicePanel();
	ui->tabWidget->addTab(devicePanel, tr("Devices"));

	auto *instrumentPanel = new InstrumentPanel();
	widgets.append(instrumentPanel);
	ui->tabWidget->addTab(instrumentPanel, tr("Instruments"));

	for (QWidget *& widget: widgets)
	{
		connect(devicePanel, SIGNAL(inputChanged(MIDIInput*)), widget, SLOT(setInputDevice(MIDIInput*)));
		connect(devicePanel, SIGNAL(outputChanged(MIDIOutput*)), widget, SLOT(setOutputDevice(MIDIOutput*)));
	}
}

// ------------------------------------------------------------------------------------------------
MainWindow::~MainWindow()
{
	delete ui;
}
<|endoftext|>


<commit_before>#include <iostream>

#include "libaps.h"
#include "constants.h"
#include <thread>
#include <string>
#include <algorithm>

#include <concol.h>

#include "EthernetControl.h"

using namespace std;

// command options functions taken from:
// http://stackoverflow.com/questions/865668/parse-command-line-arguments
string getCmdOption(char ** begin, char ** end, const std::string & option)
{
  char ** itr = std::find(begin, end, option);
  if (itr != end && ++itr != end)
  {
    return string(*itr);
  }
  return "";
}

bool cmdOptionExists(char** begin, char** end, const std::string& option)
{
  return std::find(begin, end, option) != end;
}

int main (int argc, char* argv[])
{

  setcolor(red,black);
  cout<<"BBN AP2 Test Executable" << endl;
  setcolor(white,black);

  set_logging_level(5);

  // lookup based on device name
  //string dev("\\Device\\NPF_{F47ACE9E-1961-4A8E-BA14-2564E3764BFA}");

  // lookup based on description
  string dev("Intel(R) 82579LM Gigabit Network Connection");

  set_ethernet_active(const_cast<char*>(dev.c_str()),true);

  int numDevices = get_numDevices();

  setcolor(red,black);
  cout << numDevices << " APS device" << (numDevices > 1 ? "s": "")  << " found" << endl;
  setcolor(white,black);

  if (numDevices < 1)
  	return 0;

  setcolor(red,black);
  cout << "Attempting to initialize libaps" << endl;
  setcolor(white,black);

  init();

  setcolor(red,black);
  cout << "Attempting to get serials" << endl;
  setcolor(white,black);

  char serialBuffer[100];

  for (int cnt; cnt < numDevices; cnt++) {
  	get_deviceSerial(cnt, serialBuffer);
    setcolor(red,black);
  	cout << "Device " << cnt << " serial #: " << serialBuffer << endl;
    setcolor(white,black);
  }

  int rc;
  rc = connect_by_ID(0);

  setcolor(red,black);
  cout << "connect_by_ID(0) returned " << rc << endl;
  setcolor(white,black);

  rc = initAPS(0, "../dummyBitfile.bit", 0);

  setcolor(red,black);
  cout << "initAPS(0) returned " << rc << endl;
  setcolor(white,black);

#if 0
  cout << "Set sample rate " << endl;

  set_sampleRate(0,100);

  cout << "current PLL frequency = " << get_sampleRate(0) << " MHz" << endl;

  cout << "setting trigger source = EXTERNAL" << endl;

  set_trigger_source(0, EXTERNAL);

  cout << "get trigger source returns " << ((get_trigger_source(0) == INTERNAL) ? "INTERNAL" : "EXTERNAL") << endl;

  cout << "setting trigger source = INTERNAL" << endl;

  set_trigger_source(0, INTERNAL);

  cout << "get trigger source returns " << ((get_trigger_source(0) == INTERNAL) ? "INTERNAL" : "EXTERNAL") << endl;

  cout << "get channel(0) enable: " << get_channel_enabled(0,0) << endl;

  cout << "set channel(0) enabled = 1" << endl;

  set_channel_enabled(0,0,true);

  const int wfs = 1000;
  short wf[wfs];
  for (int cnt = 0; cnt < wfs; cnt++)
    wf[cnt] = (cnt < wfs/2) ? 32767 : -32767;

  cout << "loading waveform" << endl;

  set_waveform_int(0, 0, wf, wfs);

  cout << "Running" << endl;

  set_sampleRate(0,50);

  run(0);

  std::this_thread::sleep_for(std::chrono::seconds(10));

  cout << "Stopping" << endl;

  stop(0);

  set_channel_enabled(0,0,false);

  cout << "get channel(0) enable: " << get_channel_enabled(0,0) << endl;

  rc = disconnect_by_ID(0);

  cout << "disconnect_by_ID(0) returned " << rc << endl;
#endif
  return 0;
}<commit_msg>Enabled remainder of test<commit_after>#include <iostream>

#include "libaps.h"
#include "constants.h"
#include <thread>
#include <string>
#include <algorithm>

#include <concol.h>

#include "EthernetControl.h"

using namespace std;

// command options functions taken from:
// http://stackoverflow.com/questions/865668/parse-command-line-arguments
string getCmdOption(char ** begin, char ** end, const std::string & option)
{
  char ** itr = std::find(begin, end, option);
  if (itr != end && ++itr != end)
  {
    return string(*itr);
  }
  return "";
}

bool cmdOptionExists(char** begin, char** end, const std::string& option)
{
  return std::find(begin, end, option) != end;
}

int main (int argc, char* argv[])
{

  setcolor(red,black);
  cout<<"BBN AP2 Test Executable" << endl;
  setcolor(white,black);

  int dbgLevel = 4;
  if (argc >= 2) {
    dbgLevel = atoi(argv[1]);
  }

  set_logging_level(dbgLevel);

  // lookup based on device name
  //string dev("\\Device\\NPF_{F47ACE9E-1961-4A8E-BA14-2564E3764BFA}");

  // lookup based on description
  string dev("Intel(R) 82579LM Gigabit Network Connection");

  set_ethernet_active(const_cast<char*>(dev.c_str()),true);

  int numDevices = get_numDevices();

  setcolor(red,black);
  cout << numDevices << " APS device" << (numDevices > 1 ? "s": "")  << " found" << endl;
  setcolor(white,black);

  if (numDevices < 1)
  	return 0;

  setcolor(red,black);
  cout << "Attempting to initialize libaps" << endl;
  setcolor(white,black);

  init();

  setcolor(red,black);
  cout << "Attempting to get serials" << endl;
  setcolor(white,black);

  char serialBuffer[100];

  for (int cnt; cnt < numDevices; cnt++) {
  	get_deviceSerial(cnt, serialBuffer);
    setcolor(red,black);
  	cout << "Device " << cnt << " serial #: " << serialBuffer << endl;
    setcolor(white,black);
  }

  int rc;
  rc = connect_by_ID(0);

  setcolor(red,black);
  cout << "connect_by_ID(0) returned " << rc << endl;
  setcolor(white,black);

  rc = initAPS(0, "../dummyBitfile.bit", 0);

  setcolor(red,black);
  cout << "initAPS(0) returned " << rc << endl;
  setcolor(white,black);

  cout << "Set sample rate " << endl;

  set_sampleRate(0,100);

  cout << "current PLL frequency = " << get_sampleRate(0) << " MHz" << endl;

  cout << "setting trigger source = EXTERNAL" << endl;

  set_trigger_source(0, EXTERNAL);

  cout << "get trigger source returns " << ((get_trigger_source(0) == INTERNAL) ? "INTERNAL" : "EXTERNAL") << endl;

  cout << "setting trigger source = INTERNAL" << endl;

  set_trigger_source(0, INTERNAL);

  cout << "get trigger source returns " << ((get_trigger_source(0) == INTERNAL) ? "INTERNAL" : "EXTERNAL") << endl;

  cout << "get channel(0) enable: " << get_channel_enabled(0,0) << endl;

  cout << "set channel(0) enabled = 1" << endl;

  set_channel_enabled(0,0,true);

  const int wfs = 1000;
  short wf[wfs];
  for (int cnt = 0; cnt < wfs; cnt++)
    wf[cnt] = (cnt < wfs/2) ? 32767 : -32767;

  cout << "loading waveform" << endl;

  set_waveform_int(0, 0, wf, wfs);

  cout << "Running" << endl;

  set_sampleRate(0,50);

  run(0);

  std::this_thread::sleep_for(std::chrono::seconds(10));

  cout << "Stopping" << endl;

  stop(0);

  set_channel_enabled(0,0,false);

  cout << "get channel(0) enable: " << get_channel_enabled(0,0) << endl;

  rc = disconnect_by_ID(0);

  cout << "disconnect_by_ID(0) returned " << rc << endl;

  return 0;
}<|endoftext|>


<commit_before>#include <iostream>
#include <iomanip>

#include "TTreeFormula.h"
#include "TCanvas.h"
#include "TH1I.h"
#include "TH1.h"

#include "CutflowMaker.h"

ClassImp(CutflowMaker)

//--------------------------------------------------------------------
CutflowMaker::CutflowMaker()
{
  fCutNames.resize(0);
  fCuts.resize(0);
  fYields.resize(0);
}

//--------------------------------------------------------------------
void
CutflowMaker::GetCutflow()
{
  if (fYields.size() == 0 && fTree != NULL) {
    std::vector<TTreeFormula*> formulae;
    TTreeFormula *tempFormula;
    for (UInt_t iCut = 0; iCut != fCuts.size(); ++iCut) {
      tempFormula = new TTreeFormula(fCutNames[iCut],fCuts[iCut],fTree);
      formulae.push_back(tempFormula);
      fYields.push_back(0);
    }
    Int_t numEntries = fTree->GetEntriesFast();
    for (Int_t iEntry = 0; iEntry != numEntries; ++iEntry) {
      fTree->GetEntry(iEntry);
      for (UInt_t iCut = 0; iCut != formulae.size(); ++iCut) {
        if (formulae[iCut]->EvalInstance() == 0)
          break;
        ++fYields[iCut];
      }
    }
  }
}

//--------------------------------------------------------------------
void
CutflowMaker::PrintCutflow(Bool_t OnlyNums)
{
  GetCutflow();
  std::cout << std::setw(15);
  for (UInt_t iCut = 0; iCut != fCuts.size(); ++iCut) {
    if (!OnlyNums)
      std::cout << fCutNames[iCut];
    if (fTree != NULL)
      std::cout << fYields[iCut];
    std::cout << std::endl;
  }
}

//--------------------------------------------------------------------
void
CutflowMaker::MakePlot(TString name)
{
  GetCutflow();
  TH1I* theHist = new TH1I("cutflow",";Cut;Number of Events",fCuts.size(),0,fCuts.size());
  for (UInt_t iCut = 0; iCut != fCuts.size(); ++iCut) {
    theHist->GetXaxis()->SetBinLabel(iCut+1,fCutNames[iCut]);
    theHist->SetBinContent(iCut+1,fYields[iCut]);
  }
  theHist->SetLineWidth(2);

  TCanvas* theCanvas = new TCanvas("canvas",";Cut;Number of Events");
  theHist->Draw();

  theCanvas->SaveAs(name + ".pdf");
  theCanvas->SaveAs(name + ".png");
  theCanvas->SaveAs(name + ".C");
}
<commit_msg>Formatted output of cutflow.<commit_after>#include <iostream>
#include <iomanip>

#include "TTreeFormula.h"
#include "TCanvas.h"
#include "TH1I.h"
#include "TH1.h"

#include "CutflowMaker.h"

ClassImp(CutflowMaker)

//--------------------------------------------------------------------
CutflowMaker::CutflowMaker()
{
  fCutNames.resize(0);
  fCuts.resize(0);
  fYields.resize(0);
}

//--------------------------------------------------------------------
void
CutflowMaker::GetCutflow()
{
  if (fYields.size() == 0 && fTree != NULL) {
    std::vector<TTreeFormula*> formulae;
    TTreeFormula *tempFormula;
    for (UInt_t iCut = 0; iCut != fCuts.size(); ++iCut) {
      tempFormula = new TTreeFormula(fCutNames[iCut],fCuts[iCut],fTree);
      formulae.push_back(tempFormula);
      fYields.push_back(0);
    }
    Int_t numEntries = fTree->GetEntriesFast();
    for (Int_t iEntry = 0; iEntry != numEntries; ++iEntry) {
      fTree->GetEntry(iEntry);
      for (UInt_t iCut = 0; iCut != formulae.size(); ++iCut) {
        if (formulae[iCut]->EvalInstance() == 0)
          break;
        ++fYields[iCut];
      }
    }
  }
}

//--------------------------------------------------------------------
void
CutflowMaker::PrintCutflow(Bool_t OnlyNums)
{
  GetCutflow();
  std::cout << std::endl;
  for (UInt_t iCut = 0; iCut != fCuts.size(); ++iCut) {
    if (!OnlyNums) {
      std::cout << std::setw(20);
      std::cout << fCutNames[iCut] << ": ";
    }
    if (fTree != NULL) {
      std::cout << std::setw(15);
      std::cout << fYields[iCut];
    }
    std::cout << std::endl;
  }
  std::cout << std::endl;
}

//--------------------------------------------------------------------
void
CutflowMaker::MakePlot(TString name)
{
  GetCutflow();
  TH1I* theHist = new TH1I("cutflow",";;Number of Events",fCuts.size(),0,fCuts.size());
  for (UInt_t iCut = 0; iCut != fCuts.size(); ++iCut) {
    theHist->GetXaxis()->SetBinLabel(iCut+1,fCutNames[iCut]);
    theHist->SetBinContent(iCut+1,fYields[iCut]);
  }
  theHist->SetLineWidth(2);

  TCanvas* theCanvas = new TCanvas("canvas",";;Number of Events");
  theHist->Draw();

  theCanvas->SaveAs(name + ".pdf");
  theCanvas->SaveAs(name + ".png");
  theCanvas->SaveAs(name + ".C");
}
<|endoftext|>