<commit_before>/**
 * C S O U N D   V S T
 *
 * A VST plugin version of Csound, with Python scripting.
 *
 * L I C E N S E
 *
 * This software is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#include "CppSound.hpp"

#include <cstdio>
#include <cstring>

CppSound::CppSound() : Csound(),
                       go(false),
                       isCompiled(false),
                       isPerforming(false),
                       spoutSize(0)
{
  SetHostData((CSOUND *)0);
}

CppSound::~CppSound()
{
}

int CppSound::compile(int argc, char **argv_)
{
  Message("BEGAN CppSound::compile(%d, %p)...\n", argc, argv_);
  go = false;
  int returnValue = Compile(argc, argv_);
  spoutSize = GetKsmps() * GetNchnls() * sizeof(MYFLT);
  if(returnValue)
    {
      isCompiled = false;
    }
  else
    {
      const char *outfilename = GetOutputFileName();
      if (outfilename) {
        renderedSoundfile = outfilename;
      }
      isCompiled = true;
      go = true;
    }
  Message("ENDED CppSound::compile.\n");
  return returnValue;
}

int CppSound::compile()
{
  Message("BEGAN CppSound::compile()...\n");
  if(getCommand().length() <= 0)
    {
      Message("No Csound command.\n");
      return 0;
    }
  scatterArgs(getCommand(), const_cast< std::vector<std::string> & >(args), const_cast< std::vector<char *> &>(argv));
  int returnValue = compile(args.size(), &argv.front());
  Message("ENDED CppSound::compile.\n");
  return returnValue;
}

int CppSound::perform(int argc, char **argv_)
{
  double beganAt = double(clock()) / double(CLOCKS_PER_SEC);
  isCompiled = false;
  go = false;
  Message("BEGAN CppSound::perform(%d, %p)...\n", argc, argv_);
  if(argc <= 0)
    {
      Message("ENDED CppSound::perform without compiling or performing.\n");
      return 0;
    }
  int result = compile(argc, argv_);
  if(result == -1)
    {
      return result;
    }
  for(result = 0; (result == 0) && go; )
    {
      result = PerformKsmps();
    }
  cleanup();
  double endedAt = double(clock()) / double(CLOCKS_PER_SEC);
  double elapsed = endedAt - beganAt;
  Message("Elapsed time = %f seconds.\n", elapsed);
  Message("ENDED CppSound::perform.\n");
  isCompiled = false;
  isPerforming = false;
  return 1;
}

int CppSound::perform()
{
  int returnValue = 0;
  std::string command = getCommand();
  if(command.find("-") == 0)
    {
      const char *argv_[] = {"csound", getFilename().c_str(), 0};
      returnValue = perform(2, (char **)argv_);
    }
  else
    {
      scatterArgs(command, const_cast< std::vector<std::string> & >(args), const_cast< std::vector<char *> &>(argv));
      returnValue = perform(args.size(), &argv.front());
    }
  return returnValue;
}

void CppSound::stop()
{
  Message("RECEIVED CppSound::stop...\n");
  isCompiled = false;
  isPerforming = false;
  go = false;
}

CSOUND *CppSound::getCsound()
{
  return csound;
}

int CppSound::performKsmps(bool absolute)
{
  if(absolute){
    return PerformKsmpsAbsolute();
  }
  else {
    return PerformKsmps();
  }
}

void CppSound::cleanup()
{
  Cleanup();
  Reset();
}

size_t CppSound::getSpoutSize() const
{
  return spoutSize;
}

std::string CppSound::getOutputSoundfileName() const
{
  return renderedSoundfile;
}

void CppSound::inputMessage(const char *istatement)
{
  InputMessage(istatement);
}

void CppSound::write(const char *text)
{
  Message("%s", text);
}

long CppSound::getThis()
{
  return (long) this;
}

CsoundFile *CppSound::getCsoundFile()
{
  return dynamic_cast<CsoundFile *>(this);
}

bool CppSound::getIsCompiled() const
{
  return isCompiled;
}

void CppSound::setIsPerforming(bool isPerforming)
{
  this->isPerforming = isPerforming;
}

bool CppSound::getIsPerforming() const
{
  return isPerforming;
}

bool CppSound::getIsGo()
{
  if(csound) {
    if(GetSpin() && GetSpout()) {
      return go;
    }
  }
  return false;
}

extern "C"
{
  int PyRun_SimpleString(const char *string);
}

static void pythonMessageCallback(CSOUND *csound, int attr, const char *format, va_list valist)
{
  static char buffer[0x1000];
  static char buffer1[0x1000];
  vsprintf(buffer, format, valist);
  static std::string actualBuffer;
  static std::string lineBuffer;
  actualBuffer.append(buffer);
  size_t position = 0;
  while((position = actualBuffer.find("\n")) != std::string::npos)
    {
      lineBuffer = actualBuffer.substr(0, position);
      actualBuffer.erase(0, position + 1);
#ifndef MSVC
      actualBuffer.clear();
#endif
      sprintf(buffer1, "print '''%s'''", lineBuffer.c_str());
      PyRun_SimpleString(buffer1);
    }
}

void CppSound::setPythonMessageCallback()
{
  SetMessageCallback(pythonMessageCallback);
}

<commit_msg>Implement CppSound::stop with Csound::Stop.<commit_after>/**
 * C S O U N D   V S T
 *
 * A VST plugin version of Csound, with Python scripting.
 *
 * L I C E N S E
 *
 * This software is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#include "CppSound.hpp"

#include <cstdio>
#include <cstring>

CppSound::CppSound() : Csound(),
                       go(false),
                       isCompiled(false),
                       isPerforming(false),
                       spoutSize(0)
{
  SetHostData((CSOUND *)0);
}

CppSound::~CppSound()
{
}

int CppSound::compile(int argc, char **argv_)
{
  Message("BEGAN CppSound::compile(%d, %p)...\n", argc, argv_);
  go = false;
  int returnValue = Compile(argc, argv_);
  spoutSize = GetKsmps() * GetNchnls() * sizeof(MYFLT);
  if(returnValue)
    {
      isCompiled = false;
    }
  else
    {
      const char *outfilename = GetOutputFileName();
      if (outfilename) {
        renderedSoundfile = outfilename;
      }
      isCompiled = true;
      go = true;
    }
  Message("ENDED CppSound::compile.\n");
  return returnValue;
}

int CppSound::compile()
{
  Message("BEGAN CppSound::compile()...\n");
  if(getCommand().length() <= 0)
    {
      Message("No Csound command.\n");
      return 0;
    }
  scatterArgs(getCommand(), const_cast< std::vector<std::string> & >(args), const_cast< std::vector<char *> &>(argv));
  int returnValue = compile(args.size(), &argv.front());
  Message("ENDED CppSound::compile.\n");
  return returnValue;
}

int CppSound::perform(int argc, char **argv_)
{
  double beganAt = double(clock()) / double(CLOCKS_PER_SEC);
  isCompiled = false;
  go = false;
  Message("BEGAN CppSound::perform(%d, %p)...\n", argc, argv_);
  if(argc <= 0)
    {
      Message("ENDED CppSound::perform without compiling or performing.\n");
      return 0;
    }
  int result = compile(argc, argv_);
  if(result == -1)
    {
      return result;
    }
  for(result = 0; (result == 0) && go; )
    {
      result = PerformKsmps();
    }
  cleanup();
  double endedAt = double(clock()) / double(CLOCKS_PER_SEC);
  double elapsed = endedAt - beganAt;
  Message("Elapsed time = %f seconds.\n", elapsed);
  Message("ENDED CppSound::perform.\n");
  isCompiled = false;
  isPerforming = false;
  return 1;
}

int CppSound::perform()
{
  int returnValue = 0;
  std::string command = getCommand();
  if(command.find("-") == 0)
    {
      const char *argv_[] = {"csound", getFilename().c_str(), 0};
      returnValue = perform(2, (char **)argv_);
    }
  else
    {
      scatterArgs(command, const_cast< std::vector<std::string> & >(args), const_cast< std::vector<char *> &>(argv));
      returnValue = perform(args.size(), &argv.front());
    }
  return returnValue;
}

void CppSound::stop()
{
  Message("RECEIVED CppSound::stop...\n");
  isCompiled = false;
  isPerforming = false;
  go = false;
  Stop();
}

CSOUND *CppSound::getCsound()
{
  return csound;
}

int CppSound::performKsmps(bool absolute)
{
  if(absolute){
    return PerformKsmpsAbsolute();
  }
  else {
    return PerformKsmps();
  }
}

void CppSound::cleanup()
{
  Cleanup();
  Reset();
}

size_t CppSound::getSpoutSize() const
{
  return spoutSize;
}

std::string CppSound::getOutputSoundfileName() const
{
  return renderedSoundfile;
}

void CppSound::inputMessage(const char *istatement)
{
  InputMessage(istatement);
}

void CppSound::write(const char *text)
{
  Message("%s", text);
}

long CppSound::getThis()
{
  return (long) this;
}

CsoundFile *CppSound::getCsoundFile()
{
  return dynamic_cast<CsoundFile *>(this);
}

bool CppSound::getIsCompiled() const
{
  return isCompiled;
}

void CppSound::setIsPerforming(bool isPerforming)
{
  this->isPerforming = isPerforming;
}

bool CppSound::getIsPerforming() const
{
  return isPerforming;
}

bool CppSound::getIsGo()
{
  if(csound) {
    if(GetSpin() && GetSpout()) {
      return go;
    }
  }
  return false;
}

extern "C"
{
  int PyRun_SimpleString(const char *string);
}

static void pythonMessageCallback(CSOUND *csound, int attr, const char *format, va_list valist)
{
  static char buffer[0x1000];
  static char buffer1[0x1000];
  vsprintf(buffer, format, valist);
  static std::string actualBuffer;
  static std::string lineBuffer;
  actualBuffer.append(buffer);
  size_t position = 0;
  while((position = actualBuffer.find("\n")) != std::string::npos)
    {
      lineBuffer = actualBuffer.substr(0, position);
      actualBuffer.erase(0, position + 1);
#ifndef MSVC
      actualBuffer.clear();
#endif
      sprintf(buffer1, "print '''%s'''", lineBuffer.c_str());
      PyRun_SimpleString(buffer1);
    }
}

void CppSound::setPythonMessageCallback()
{
  SetMessageCallback(pythonMessageCallback);
}

<|endoftext|>


<commit_before>#include "WindowsAPIs.h"
#include "TaskIcon.h"

INT WINAPI WinMain(HINSTANCE hinst, HINSTANCE, LPSTR, INT)
{
    hinstance = hinst;

    TaskIcon().MessageLoop();

    return 0;
}
<commit_msg>Enable XINPUT right away maybe?<commit_after>#include "WindowsAPIs.h"
#include "TaskIcon.h"

INT WINAPI WinMain(HINSTANCE hinst, HINSTANCE, LPSTR, INT)
{
    hinstance = hinst;

    XInputEnable(TRUE);
    TaskIcon().MessageLoop();

    return 0;
}
<|endoftext|>


<commit_before><commit_msg>Sequencer: Eliminate magic values where applicable<commit_after><|endoftext|>


<commit_before>// Copyright 2018, Intel Corporation

#include "tile/codegen/unroll.h"

#include "base/util/logging.h"
#include "base/util/throw.h"
#include "tile/stripe/stripe.h"

namespace vertexai {
namespace tile {
namespace codegen {

using namespace stripe;  // NOLINT

namespace {

struct IndexValue {
  const Index* idx;
  size_t value;
};

using EnumerateFunc = std::function<void(const std::vector<IndexValue>& idxs)>;

void EnumerateIndexes(const std::vector<IndexValue>& idxs, size_t idx_num, const EnumerateFunc& func) {
  if (idx_num == idxs.size()) {
    func(idxs);
  } else {
    for (size_t i = 0; i < idxs[idx_num].idx->range; i++) {
      auto next = idxs;
      next[idx_num].value = i;
      EnumerateIndexes(next, idx_num + 1, func);
    }
  }
}

void EvalWithValues(Block* block, const std::map<std::string, int64_t>& fixed) {
  IVLOG(3, "EvalWithValues> block: " << block->name << ", fixed: " << fixed);
  block->location = PartialEval(block->location, fixed);
  for (auto& ref : block->refs) {
    ref.mut().location = PartialEval(ref.location, fixed);
    for (auto& aff : ref.mut().access) {
      aff = aff.partial_eval(fixed);
    }
    if (ref.cache_unit) {
      ref.mut().cache_unit = ref.cache_unit->partial_eval(fixed);
    }
  }
  for (auto& constraint : block->constraints) {
    constraint = constraint.partial_eval(fixed);
  }
  for (const auto& stmt : block->stmts) {
    auto inner = Block::Downcast(stmt);
    if (inner) {
      for (auto& idx : inner->idxs) {
        idx.affine = idx.affine.partial_eval(fixed);
      }
      std::map<std::string, int64_t> next;
      for (const auto& item : fixed) {
        if (item.first[0] == '#') {
          next.emplace(item.first, item.second);
        }
      }
      std::vector<std::string> prune_idxs;
      for (const auto& idx : inner->idxs) {
        if (idx.range == 1 && idx.affine.isConstant()) {
          prune_idxs.push_back(idx.name);
          next.emplace(idx.name, idx.affine.constant());
        }
      }
      EvalWithValues(inner.get(), next);
      for (const auto& idx_name : prune_idxs) {
        auto it = std::find_if(inner->idxs.begin(), inner->idxs.end(),
                               [&idx_name](const Index& idx) { return idx.name == idx_name; });
        inner->idxs.erase(it);
      }
    }
  }
}

struct ExpansionRule {
  std::string rule;
  std::string idx_name() const { return rule; }
  std::string tag_name() const { return rule.substr(1); }
  bool is_valid() const { return !rule.empty(); }
  bool is_tag() const { return is_valid() && rule.substr(0, 1) == "#"; }
};

struct ExpansionValue {
  size_t last_stride = 1;
  size_t value = 0;

  void operator+=(const IndexValue& idx_val) {
    value += last_stride * idx_val.value;
    last_stride *= idx_val.idx->range;
  }
};

using RefMap = std::map<std::tuple<std::string, std::vector<stripe::Affine>>, std::string>;

void EvalInner(Block* outer,                         //
               Block* block,                         //
               RefMap* ref_map,                      //
               const std::vector<IndexValue>& idxs,  //
               const proto::UnrollPass& options) {
  IVLOG(3, "EvalInner> " << outer->name << " -> " << block->name);
  std::map<std::string, int64_t> fixed;
  ExpansionRule rule{options.expand_idx()};
  ExpansionValue expand_val;
  std::stringstream ss;
  ss << "%";
  if (!options.part_name().empty()) {
    ss << options.part_name();
  }
  for (const auto& idx_val : idxs) {
    fixed.emplace(idx_val.idx->name, idx_val.value);
    ss << "_" << idx_val.idx->name << "_" << idx_val.value;
    if (rule.is_tag()) {
      // The rule is tagged, like: '#foo'. Accumulate tagged idxs into primary.
      if (idx_val.idx->has_tag(rule.tag_name())) {
        expand_val += idx_val;
      }
    } else if (rule.is_valid()) {
      // The rule is not tagged, like: 'foo'. Accumulate specifc idx into primary.
      if (idx_val.idx->name == rule.idx_name()) {
        expand_val += idx_val;
      }
    }
  }
  if (rule.is_valid()) {
    fixed.emplace(rule.idx_name(), expand_val.value);
  }
  EvalWithValues(block, fixed);
  for (const auto& stmt : block->stmts) {
    auto inner = Block::Downcast(stmt);
    if (!inner) {
      continue;
    }
    inner->name += ss.str();
    for (auto& inner_ref : inner->refs) {
      if (inner_ref.from.empty()) {
        continue;
      }
      auto block_ref = block->ref_by_into(inner_ref.from);
      for (size_t i = 0; i < inner_ref.access.size(); i++) {
        inner_ref.mut().access[i] += block_ref->access[i];
      }
      auto outer_ref = outer->ref_by_into(block_ref->from);
      IVLOG(3, "  outer_ref: " << *outer_ref);
      IVLOG(3, "  block_ref: " << *block_ref);
      IVLOG(3, "  inner_ref: " << inner_ref);
      inner_ref.mut().from = block_ref->from;
      IVLOG(3, "    from = " << inner_ref.from);
      if (!options.make_views()) {
        continue;
      }
      if (block_ref->interior_shape == outer_ref->interior_shape) {
        IVLOG(3, "    no view, same shape");
        continue;
      }
      auto key = std::make_tuple(outer_ref->from, inner_ref.access);
      auto it_inserted = ref_map->emplace(key, outer_ref->into());
      if (it_inserted.second) {
        it_inserted.first->second = outer->unique_ref_name(outer_ref->into());
      }
      auto view = block_ref->WithInto(it_inserted.first->second);
      view.from = outer_ref->from;
      IVLOG(3, "    make view: " << view.into() << " from: " << view.from << " via: " << block_ref->from);
      if (inner_ref.cache_unit || outer_ref->cache_unit) {
        IVLOG(3, "    with cache: " << *outer_ref->cache_unit);
        view.cache_unit = outer_ref->cache_unit;
      }
      for (size_t i = 0; i < inner_ref.access.size(); i++) {
        auto const_access = block_ref->access[i].constant();
        view.access[i] = outer_ref->access[i] + const_access;
        inner_ref.mut().access[i] -= const_access;
      }
      inner_ref.mut().from = view.into();
      IVLOG(2, "view: " << view);
      if (outer->ref_by_into(view.into(), false) == outer->refs.end()) {
        outer->refs.emplace(std::move(view));
      }
    }
  }
}

void UnrollBlock(Block* outer,                //
                 Block* block,                //
                 const StatementIt& it_stmt,  //
                 const Tags& reqs,            //
                 const proto::UnrollPass& options) {
  if (block->has_tags(reqs)) {
    RefMap ref_map;
    std::vector<IndexValue> idxs;
    idxs.reserve(block->idxs.size());
    for (const auto& idx : block->idxs) {
      idxs.emplace_back(IndexValue{&idx, 0});
    }
    EnumerateIndexes(idxs, 0, [&](const std::vector<IndexValue>& idxs) {
      auto clone = CloneBlock(*block);
      EvalInner(outer, clone.get(), &ref_map, idxs, options);
      for (const auto& stmt : clone->stmts) {
        outer->stmts.insert(it_stmt, stmt);
      }
    });
    outer->stmts.erase(it_stmt);
    // Dependencies become invalid after a stmt is removed
    for (auto& stmt : outer->stmts) {
      stmt->deps.clear();
    }
  } else {
    PreIterate(block, [&](const StatementIt& it) {
      auto inner = Block::Downcast(*it);
      if (inner) {
        UnrollBlock(block, inner.get(), it, reqs, options);
      }
    });
  }
}

}  // namespace

void UnrollPass(Block* root, const proto::UnrollPass& options) {
  auto reqs = FromProto(options.reqs());
  PreIterate(root, [&](const StatementIt& it) {
    auto inner = Block::Downcast(*it);
    if (inner) {
      UnrollBlock(root, inner.get(), it, reqs, options);
    }
  });
}

}  // namespace codegen
}  // namespace tile
}  // namespace vertexai
<commit_msg>Add 'in' to aggregated output refs during unroll<commit_after>// Copyright 2018, Intel Corporation

#include "tile/codegen/unroll.h"

#include "base/util/logging.h"
#include "base/util/throw.h"
#include "tile/codegen/alias.h"
#include "tile/stripe/stripe.h"

namespace vertexai {
namespace tile {
namespace codegen {

using namespace stripe;  // NOLINT

namespace {

struct IndexValue {
  const Index* idx;
  size_t value;
};

using EnumerateFunc = std::function<void(const std::vector<IndexValue>& idxs)>;

void EnumerateIndexes(const std::vector<IndexValue>& idxs, size_t idx_num, const EnumerateFunc& func) {
  if (idx_num == idxs.size()) {
    func(idxs);
  } else {
    for (size_t i = 0; i < idxs[idx_num].idx->range; i++) {
      auto next = idxs;
      next[idx_num].value = i;
      EnumerateIndexes(next, idx_num + 1, func);
    }
  }
}

void EvalWithValues(Block* block, const std::map<std::string, int64_t>& fixed) {
  IVLOG(3, "EvalWithValues> block: " << block->name << ", fixed: " << fixed);
  block->location = PartialEval(block->location, fixed);
  for (auto& ref : block->refs) {
    ref.mut().location = PartialEval(ref.location, fixed);
    for (auto& aff : ref.mut().access) {
      aff = aff.partial_eval(fixed);
    }
    if (ref.cache_unit) {
      ref.mut().cache_unit = ref.cache_unit->partial_eval(fixed);
    }
  }
  for (auto& constraint : block->constraints) {
    constraint = constraint.partial_eval(fixed);
  }
  for (const auto& stmt : block->stmts) {
    auto inner = Block::Downcast(stmt);
    if (inner) {
      for (auto& idx : inner->idxs) {
        idx.affine = idx.affine.partial_eval(fixed);
      }
      std::map<std::string, int64_t> next;
      for (const auto& item : fixed) {
        if (item.first[0] == '#') {
          next.emplace(item.first, item.second);
        }
      }
      std::vector<std::string> prune_idxs;
      for (const auto& idx : inner->idxs) {
        if (idx.range == 1 && idx.affine.isConstant()) {
          prune_idxs.push_back(idx.name);
          next.emplace(idx.name, idx.affine.constant());
        }
      }
      EvalWithValues(inner.get(), next);
      for (const auto& idx_name : prune_idxs) {
        auto it = std::find_if(inner->idxs.begin(), inner->idxs.end(),
                               [&idx_name](const Index& idx) { return idx.name == idx_name; });
        inner->idxs.erase(it);
      }
    }
  }
}

struct ExpansionRule {
  std::string rule;
  std::string idx_name() const { return rule; }
  std::string tag_name() const { return rule.substr(1); }
  bool is_valid() const { return !rule.empty(); }
  bool is_tag() const { return is_valid() && rule.substr(0, 1) == "#"; }
};

struct ExpansionValue {
  size_t last_stride = 1;
  size_t value = 0;

  void operator+=(const IndexValue& idx_val) {
    value += last_stride * idx_val.value;
    last_stride *= idx_val.idx->range;
  }
};

using RefMap = std::map<std::tuple<std::string, std::vector<stripe::Affine>>, std::string>;

void EvalInner(Block* outer,                         //
               Block* block,                         //
               RefMap* ref_map,                      //
               const std::vector<IndexValue>& idxs,  //
               const AliasMap& outer_alias_map,
               std::map<std::string, std::vector<std::vector<Extent>>>* ref_write_extents,
               const proto::UnrollPass& options) {
  IVLOG(3, "EvalInner> " << outer->name << " -> " << block->name);
  std::map<std::string, int64_t> fixed;
  ExpansionRule rule{options.expand_idx()};
  ExpansionValue expand_val;
  std::stringstream ss;
  ss << "%";
  if (!options.part_name().empty()) {
    ss << options.part_name();
  }
  for (const auto& idx_val : idxs) {
    fixed.emplace(idx_val.idx->name, idx_val.value);
    ss << "_" << idx_val.idx->name << "_" << idx_val.value;
    if (rule.is_tag()) {
      // The rule is tagged, like: '#foo'. Accumulate tagged idxs into primary.
      if (idx_val.idx->has_tag(rule.tag_name())) {
        expand_val += idx_val;
      }
    } else if (rule.is_valid()) {
      // The rule is not tagged, like: 'foo'. Accumulate specifc idx into primary.
      if (idx_val.idx->name == rule.idx_name()) {
        expand_val += idx_val;
      }
    }
  }
  if (rule.is_valid()) {
    fixed.emplace(rule.idx_name(), expand_val.value);
  }
  EvalWithValues(block, fixed);

  AliasMap block_alias_map{outer_alias_map, block};
  std::map<std::string, std::vector<std::vector<Extent>>> current_ref_write_extents;
  for (const auto& block_ref : block->refs) {
    if (!IsWriteDir(block_ref.dir)) {
      continue;
    }

    const auto& ai = block_alias_map.at(block_ref.into());

    if (block_ref.agg_op.size() && !IsReadDir(block_ref.dir)) {
      // We're aggregating into this refinement, so as we unroll, we
      // need to add in the read direction if the underlying memory
      // overlaps with any refinement previously written by an
      // unrolled step.
      auto name_extents = ref_write_extents->find(ai.base_name);
      if (name_extents != ref_write_extents->end()) {
        bool found_overlap = false;
        for (const auto& extents : name_extents->second) {
          if (CheckOverlap(ai.extents, extents)) {
            found_overlap = true;
            break;
          }
        }
        if (found_overlap) {
          block_ref.mut().dir = RefDir::InOut;
        }
      }
    }

    // Keep track of the fact that we're writing to this ref, so
    // that we can add the read direction to affected subsequent
    // blocks as needed.
    current_ref_write_extents[ai.base_name].emplace_back(ai.extents);
  }

  // Accumulate the extents written by the current block into the extents tracked over the unrolling.
  for (auto& ref_extents : current_ref_write_extents) {
    auto& extents = (*ref_write_extents)[ref_extents.first];
    extents.insert(extents.end(), ref_extents.second.begin(), ref_extents.second.end());
  }

  for (const auto& stmt : block->stmts) {
    auto inner = Block::Downcast(stmt);
    if (!inner) {
      continue;
    }
    inner->name += ss.str();
    for (auto& inner_ref : inner->refs) {
      if (inner_ref.from.empty()) {
        continue;
      }
      auto block_ref = block->ref_by_into(inner_ref.from);
      for (size_t i = 0; i < inner_ref.access.size(); i++) {
        inner_ref.mut().access[i] += block_ref->access[i];
      }
      inner_ref.mut().dir = UnionDir(inner_ref.dir, block_ref->dir);
      auto outer_ref = outer->ref_by_into(block_ref->from);
      IVLOG(3, "  outer_ref: " << *outer_ref);
      IVLOG(3, "  block_ref: " << *block_ref);
      IVLOG(3, "  inner_ref: " << inner_ref);
      inner_ref.mut().from = block_ref->from;
      IVLOG(3, "    from = " << inner_ref.from);
      if (!options.make_views()) {
        continue;
      }
      if (block_ref->interior_shape == outer_ref->interior_shape) {
        IVLOG(3, "    no view, same shape");
        continue;
      }
      auto key = std::make_tuple(outer_ref->from, inner_ref.access);
      auto it_inserted = ref_map->emplace(key, outer_ref->into());
      if (it_inserted.second) {
        it_inserted.first->second = outer->unique_ref_name(outer_ref->into());
      }
      auto view = block_ref->WithInto(it_inserted.first->second);
      view.from = outer_ref->from;
      IVLOG(3, "    make view: " << view.into() << " from: " << view.from << " via: " << block_ref->from);
      if (inner_ref.cache_unit || outer_ref->cache_unit) {
        IVLOG(3, "    with cache: " << *outer_ref->cache_unit);
        view.cache_unit = outer_ref->cache_unit;
      }
      for (size_t i = 0; i < inner_ref.access.size(); i++) {
        auto const_access = block_ref->access[i].constant();
        view.access[i] = outer_ref->access[i] + const_access;
        inner_ref.mut().access[i] -= const_access;
      }
      inner_ref.mut().from = view.into();
      IVLOG(2, "view: " << view);
      if (outer->ref_by_into(view.into(), false) == outer->refs.end()) {
        outer->refs.emplace(std::move(view));
      }
    }
  }
}

void UnrollBlock(Block* outer,                     //
                 Block* block,                     //
                 const AliasMap& outer_alias_map,  //
                 const StatementIt& it_stmt,       //
                 const Tags& reqs,                 //
                 const proto::UnrollPass& options) {
  if (block->has_tags(reqs)) {
    RefMap ref_map;
    std::vector<IndexValue> idxs;
    idxs.reserve(block->idxs.size());
    for (const auto& idx : block->idxs) {
      idxs.emplace_back(IndexValue{&idx, 0});
    }
    std::map<std::string, std::vector<std::vector<Extent>>> ref_write_extents;
    EnumerateIndexes(idxs, 0, [&](const std::vector<IndexValue>& idxs) {
      auto clone = CloneBlock(*block);
      EvalInner(outer, clone.get(), &ref_map, idxs, outer_alias_map, &ref_write_extents, options);
      for (const auto& stmt : clone->stmts) {
        outer->stmts.insert(it_stmt, stmt);
      }
    });
    outer->stmts.erase(it_stmt);
    // Dependencies become invalid after a stmt is removed
    for (auto& stmt : outer->stmts) {
      stmt->deps.clear();
    }
  } else {
    AliasMap alias_map{outer_alias_map, block};
    PreIterate(block, [&](const StatementIt& it) {
      auto inner = Block::Downcast(*it);
      if (inner) {
        UnrollBlock(block, inner.get(), alias_map, it, reqs, options);
      }
    });
  }
}

}  // namespace

void UnrollPass(Block* root, const proto::UnrollPass& options) {
  auto reqs = FromProto(options.reqs());
  AliasMap base_alias_map;
  AliasMap alias_map{base_alias_map, root};
  PreIterate(root, [&](const StatementIt& it) {
    auto inner = Block::Downcast(*it);
    if (inner) {
      UnrollBlock(root, inner.get(), alias_map, it, reqs, options);
    }
  });
}

}  // namespace codegen
}  // namespace tile
}  // namespace vertexai
<|endoftext|>


<commit_before><commit_msg>fix for some potential bugs in ray tracer<commit_after><|endoftext|>


<commit_before>#include "ch.h"
#include "hal.h"
#include "stm32f4xx_conf.h"
#include "comm_usb.h"
#include "dw1000.h"
#include "chprintf.h"
#include <stdio.h>
#include <string.h>
#include "hw_conf.h"
#include <inttypes.h>

#define ANSWER_DELAY_US             5000
#define ANSWER_DELAY_TIMEUNITS      ANSWER_DELAY_US * (128*499.2)
#define TIMEUNITS_TO_US       (1/(128*499.2))

#define TX
static DW1000 *dw1000;
static dw1000_tx_conf_t tx_conf;
static uint64_t sentTimes[4];
static uint64_t receivedTimes[3];
static uint8_t state;

void rxcb(uint64_t status)
{
    if (!(status & DW_RXDFR_MASK))
    {
        chprintf((BaseSequentialStream*)&SDU1, "receive error %d\n", status);
        dw1000->ResetRX();
#ifndef TX
        dw1000->Receive( DW_TRANCEIVE_ASYNC );
#endif
        return;
    }

    uint32_t rxlen;
    uint8_t* rxbuf = dw1000->GetRXBuffer(&rxlen);

    //chprintf((BaseSequentialStream*)&SDU1, "recv: %d %d\n", state, rxbuf[0]);
    switch(rxbuf[0])
    {
        uint8_t data[17];
        uint64_t treply1;
        uint64_t tround2;
        case 0:
        case 1:
            receivedTimes[rxbuf[0]] = dw1000->GetRXTimestamp();
            state = rxbuf[0] + 1;
            data[0] = state;
            tx_conf.is_delayed = 1;
            tx_conf.dx_timestamp = receivedTimes[rxbuf[0]] + ANSWER_DELAY_TIMEUNITS;
            dw1000->ConfigureTX( &tx_conf );
            dw1000->Transmit(data, tx_conf.data_len, DW_TRANCEIVE_ASYNC);
            break;
        case 2:
            receivedTimes[rxbuf[0]] = dw1000->GetRXTimestamp();
            state = rxbuf[0] + 1;
            data[0] = state;
            treply1 = sentTimes[1] - receivedTimes[0];
            tround2 = receivedTimes[2] - sentTimes[1];
            memcpy(&data[1], &treply1, 8);
            memcpy(&data[9], &tround2, 8);
            tx_conf.is_delayed = 1;
            tx_conf.dx_timestamp = receivedTimes[rxbuf[0]] + ANSWER_DELAY_TIMEUNITS;
            dw1000->ConfigureTX( &tx_conf );
            dw1000->Transmit(data, tx_conf.data_len, DW_TRANCEIVE_ASYNC);
            break;
        case 3:
            memcpy(&treply1, &rxbuf[1], 8);
            memcpy(&tround2, &rxbuf[9], 8);
            uint64_t tround1 = receivedTimes[1] - sentTimes[0];
            uint64_t treply2 = sentTimes[2] - receivedTimes[1];
            float tround1_us = tround1 * TIMEUNITS_TO_US;
            float tround2_us = tround2 * TIMEUNITS_TO_US;
            float treply1_us = treply1 * TIMEUNITS_TO_US;
            float treply2_us = treply2 * TIMEUNITS_TO_US;
            float tprop = (tround1_us * tround2_us - treply1_us * treply2_us) / (tround1_us + tround2_us + treply1_us + treply2_us);
            float dist = tprop * 300 / 4.0;

            chprintf((BaseSequentialStream*)&SDU1, "tprop: %f %f %f %f %f %f\n", tround1_us, tround2_us, treply1_us, treply2_us, tprop, dist);
            break;
    }
}

void txcb(uint64_t status)
{
    sentTimes[state] = dw1000->GetTXTimestamp();
    //chprintf((BaseSequentialStream*)&SDU1, "sent: %d\n", sentTimes[state]);
    dw1000->Receive( DW_TRANCEIVE_ASYNC );
}

int main(void) {
    halInit();
    chSysInit();

    dw1000 = new DW1000();
    dw1000->SetCallbacks(&txcb, &rxcb);

    tx_conf.data_len = 17;
    tx_conf.is_delayed = 0;
    dw1000->ConfigureTX( &tx_conf );

    dw1000_rx_conf_t rx_conf;
    rx_conf.is_delayed = 0;
    rx_conf.timeout = 0;//0xFFFF; // ~65 ms
    dw1000->ConfigureRX( &rx_conf );

#ifndef TX
    dw1000->Receive( DW_TRANCEIVE_ASYNC );
#endif

    for (;;)
    {
#ifdef TX
        state = 0;
        uint8_t data[17];
        data[0] = state;
        tx_conf.is_delayed = 0;
        dw1000->ConfigureTX( &tx_conf );
        dw1000->Transmit(&state, tx_conf.data_len, DW_TRANCEIVE_ASYNC);
#endif
        chThdSleepMilliseconds(100);
    }
}
<commit_msg>Old files<commit_after>#include "ch.h"
#include "hal.h"
#include "stm32f4xx_conf.h"
#include "comm_usb.h"
#include "dw1000.h"
#include "chprintf.h"
#include <stdio.h>
#include <string.h>
#include "hw_conf.h"
#include <inttypes.h>

#define ANSWER_DELAY_US             5000
#define ANSWER_DELAY_TIMEUNITS      ANSWER_DELAY_US * (128*499.2)
#define TIMEUNITS_TO_US       (1/(128*499.2))

#define TX
static DW1000 *dw1000;
static dw1000_tx_conf_t tx_conf;
static uint64_t sentTimes[4];
static uint64_t receivedTimes[3];
static uint8_t state;

void rxcb(uint64_t status)
{
    if (!(status & DW_RXDFR_MASK))
    {
        chprintf((BaseSequentialStream*)&SDU1, "receive error %d\n", status);
        dw1000->ResetRX();
#ifndef TX
        dw1000->Receive( DW_TRANCEIVE_ASYNC );
#endif
        return;
    }

    uint32_t rxlen;
    uint8_t* rxbuf = dw1000->GetRXBuffer(&rxlen);

    //chprintf((BaseSequentialStream*)&SDU1, "recv: %d %d\n", state, rxbuf[0]);
    switch(rxbuf[0])
    {
        uint8_t data[17];
        uint64_t treply1;
        uint64_t tround2;
        case 0:
        case 1:
            receivedTimes[rxbuf[0]] = dw1000->GetRXTimestamp();
            state = rxbuf[0] + 1;
            data[0] = state;
            tx_conf.is_delayed = 1;
            tx_conf.dx_timestamp = receivedTimes[rxbuf[0]] + ANSWER_DELAY_TIMEUNITS;
            dw1000->ConfigureTX( &tx_conf );
            dw1000->Transmit(data, tx_conf.data_len, DW_TRANCEIVE_ASYNC);
            break;
        case 2:
            receivedTimes[rxbuf[0]] = dw1000->GetRXTimestamp();
            state = rxbuf[0] + 1;
            data[0] = state;
            treply1 = sentTimes[1] - receivedTimes[0];
            tround2 = receivedTimes[2] - sentTimes[1];
            memcpy(&data[1], &treply1, 8);
            memcpy(&data[9], &tround2, 8);
            tx_conf.is_delayed = 1;
            tx_conf.dx_timestamp = receivedTimes[rxbuf[0]] + ANSWER_DELAY_TIMEUNITS;
            dw1000->ConfigureTX( &tx_conf );
            dw1000->Transmit(data, tx_conf.data_len, DW_TRANCEIVE_ASYNC);
            break;
        case 3:
            memcpy(&treply1, &rxbuf[1], 8);
            memcpy(&tround2, &rxbuf[9], 8);
            uint64_t tround1 = receivedTimes[1] - sentTimes[0];
            uint64_t treply2 = sentTimes[2] - receivedTimes[1];
            float tround1_us = tround1 * TIMEUNITS_TO_US;
            float tround2_us = tround2 * TIMEUNITS_TO_US;
            float treply1_us = treply1 * TIMEUNITS_TO_US;
            float treply2_us = treply2 * TIMEUNITS_TO_US;
            float tprop = (tround1_us * tround2_us - treply1_us * treply2_us) / (tround1_us + tround2_us + treply1_us + treply2_us);
            float dist = tprop * 300 - 154;

            chprintf((BaseSequentialStream*)&SDU1, "tprop: %f %f %f %f %f %f\n", tround1_us, tround2_us, treply1_us, treply2_us, tprop, dist);
            break;
    }
}

void txcb(uint64_t status)
{
    sentTimes[state] = dw1000->GetTXTimestamp();
    //chprintf((BaseSequentialStream*)&SDU1, "sent: %d\n", sentTimes[state]);
    dw1000->Receive( DW_TRANCEIVE_ASYNC );
}

int main(void) {
    halInit();
    chSysInit();

    dw1000 = new DW1000();
    dw1000->SetCallbacks(&txcb, &rxcb);

    tx_conf.data_len = 17;
    tx_conf.is_delayed = 0;
    dw1000->ConfigureTX( &tx_conf );

    dw1000_rx_conf_t rx_conf;
    rx_conf.is_delayed = 0;
    rx_conf.timeout = 0;//0xFFFF; // ~65 ms
    dw1000->ConfigureRX( &rx_conf );

#ifndef TX
    dw1000->Receive( DW_TRANCEIVE_ASYNC );
#endif

    for (;;)
    {
#ifdef TX
        state = 0;
        uint8_t data[17];
        data[0] = state;
        tx_conf.is_delayed = 0;
        dw1000->ConfigureTX( &tx_conf );
        dw1000->Transmit(&state, tx_conf.data_len, DW_TRANCEIVE_ASYNC);
#endif
        chThdSleepMilliseconds(100);
    }
}
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Vassil Vassilev <vvasilev@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include "cling/Interpreter/InterpreterCallbacks.h"

#include "cling/Interpreter/Interpreter.h"

#include "clang/AST/ASTContext.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/Sema.h"
#include "clang/Serialization/ASTReader.h"
#include "clang/Serialization/ASTDeserializationListener.h"

using namespace clang;

namespace cling {

  ///\brief Translates 'interesting' for the interpreter
  /// ASTDeserializationListener events into interpreter callback.
  ///
  class InterpreterPPCallbacks : public PPCallbacks {
  private:
    cling::InterpreterCallbacks* m_Callbacks;
  public:
    InterpreterPPCallbacks(InterpreterCallbacks* C) : m_Callbacks(C) { }
    ~InterpreterPPCallbacks() { }

    virtual void InclusionDirective(clang::SourceLocation HashLoc,
                                    const clang::Token &IncludeTok,
                                    llvm::StringRef FileName,
                                    bool IsAngled,
                                    clang::CharSourceRange FilenameRange,
                                    const clang::FileEntry *File,
                                    llvm::StringRef SearchPath,
                                    llvm::StringRef RelativePath,
                                    const clang::Module *Imported) {
      m_Callbacks->InclusionDirective(HashLoc, IncludeTok, FileName,
                                      IsAngled, FilenameRange, File,
                                      SearchPath, RelativePath, Imported);
    }

    virtual bool FileNotFound(llvm::StringRef FileName,
                              llvm::SmallVectorImpl<char>& RecoveryPath) {
      if (m_Callbacks)
        return m_Callbacks->FileNotFound(FileName, RecoveryPath);

      // Returning true would mean that the preprocessor should try to recover.
      return false;
    }
  };

  ///\brief Translates 'interesting' for the interpreter
  /// ASTDeserializationListener events into interpreter callback.
  ///
  class InterpreterDeserializationListener : public ASTDeserializationListener {
  private:
    cling::InterpreterCallbacks* m_Callbacks;
  public:
    InterpreterDeserializationListener(InterpreterCallbacks* C)
      : m_Callbacks(C) {}

    virtual void DeclRead(serialization::DeclID, const Decl *D) {
      if (m_Callbacks)
        m_Callbacks->DeclDeserialized(D);
    }

    virtual void TypeRead(serialization::TypeIdx, QualType T) {
      if (m_Callbacks)
        m_Callbacks->TypeDeserialized(T.getTypePtr());
    }
  };

  ///\brief Translates 'interesting' for the interpreter ExternalSemaSource
  /// events into interpreter callbacks.
  ///
  class InterpreterExternalSemaSource : public clang::ExternalSemaSource {
  protected:
    ///\brief The interpreter callback which are subscribed for the events.
    ///
    /// Usually the callbacks is the owner of the class and the interpreter owns
    /// the callbacks so they can't be out of sync. Eg we notifying the wrong
    /// callback class.
    ///
    InterpreterCallbacks* m_Callbacks; // we don't own it.

    Sema* m_Sema; // we don't own // FIXME: once we remove ForgetSema delete.

  public:
    InterpreterExternalSemaSource(InterpreterCallbacks* C)
      : m_Callbacks(C), m_Sema(0) {}

    ~InterpreterExternalSemaSource() {
      // FIXME: Another gross hack due to the missing multiplexing AST external
      // source see Interpreter::setCallbacks.
      if (m_Sema) {
        ASTContext& C = m_Sema->getASTContext();
        // tell the owning ptr to not delete it, the callbacks will delete it.
        if (C.ExternalSource.get() == this)
          C.ExternalSource.resetWithoutRelease();
      }
    }

    virtual void InitializeSema(Sema& S) {
      m_Sema = &S;
    }

    virtual void ForgetSema() {
      m_Sema = 0;
    }

    InterpreterCallbacks* getCallbacks() const { return m_Callbacks; }

    /// \brief Provides last resort lookup for failed unqualified lookups.
    ///
    /// This gets translated into InterpreterCallback's call.
    ///
    ///\param[out] R The recovered symbol.
    ///\param[in] S The scope in which the lookup failed.
    ///
    ///\returns true if a suitable declaration is found.
    ///
    virtual bool LookupUnqualified(clang::LookupResult& R, clang::Scope* S) {
      if (m_Callbacks) {
        return m_Callbacks->LookupObject(R, S);
      }

      return false;
    }

    virtual bool FindExternalVisibleDeclsByName(const clang::DeclContext* DC,
                                                clang::DeclarationName Name) {
      if (m_Callbacks)
        return m_Callbacks->LookupObject(DC, Name);

      return false;
    }

    // Silence warning virtual function was hidden.
    using ExternalASTSource::CompleteType;
    virtual void CompleteType(TagDecl* Tag) {
      if (m_Callbacks)
        m_Callbacks->LookupObject(Tag);
    }

    void UpdateWithNewDeclsFwd(const DeclContext *DC, DeclarationName Name,
                               llvm::ArrayRef<NamedDecl*> Decls) {
      SetExternalVisibleDeclsForName(DC, Name, Decls);
    }
  };

  InterpreterCallbacks::InterpreterCallbacks(Interpreter* interp,
                             bool enableExternalSemaSourceCallbacks/* = false*/,
                        bool enableDeserializationListenerCallbacks/* = false*/,
                                             bool enablePPCallbacks/* = false*/)
    : m_Interpreter(interp), m_IsRuntime(false) {
    Sema& SemaRef = interp->getSema();
    if (enableExternalSemaSourceCallbacks && !SemaRef.getExternalSource()) {
      m_ExternalSemaSource.reset(new InterpreterExternalSemaSource(this));
      m_ExternalSemaSource->InitializeSema(SemaRef);
      m_Interpreter->getSema().addExternalSource(m_ExternalSemaSource.get());

      // FIXME: We should add a multiplexer in the ASTContext, too.
      llvm::IntrusiveRefCntPtr<ExternalASTSource>
        astContextExternalSource(SemaRef.getExternalSource());
      clang::ASTContext& Ctx = SemaRef.getASTContext();
      // FIXME: This is a gross hack. We must make multiplexer in the astcontext
      // or a derived class that extends what we need.
      Ctx.ExternalSource.resetWithoutRelease(); //FIXME: make sure we delete it.
      Ctx.setExternalSource(astContextExternalSource);
    }

    ASTReader* Reader = m_Interpreter->getCI()->getModuleManager().get();
    if (enableDeserializationListenerCallbacks && Reader) {
      // FIXME: need to create a multiplexer if a DeserializationListener is
      // alreday present.
      m_DeserializationListener.
        reset(new InterpreterDeserializationListener(this));
      Reader->setDeserializationListener(m_DeserializationListener.get());
    }

    if (enablePPCallbacks) {
      m_PPCallbacks = new InterpreterPPCallbacks(this);
      Preprocessor& PP = m_Interpreter->getCI()->getPreprocessor();
      PP.addPPCallbacks(m_PPCallbacks);
    }
  }

  // pin the vtable here
  InterpreterCallbacks::~InterpreterCallbacks() {
    // FIXME: we have to remove the external source at destruction time. Needs
    // further tweaks of the patch in clang. This will be done later once the
    // patch is in clang's mainline.
  }

  void InterpreterCallbacks::SetIsRuntime(bool val) {
    m_IsRuntime = val;
  }

  ExternalSemaSource*
  InterpreterCallbacks::getInterpreterExternalSemaSource() const {
    return m_ExternalSemaSource.get();
  }

  ASTDeserializationListener*
  InterpreterCallbacks::getInterpreterDeserializationListener() const {
    return m_DeserializationListener.get();
  }

  bool InterpreterCallbacks::FileNotFound(llvm::StringRef FileName,
                                    llvm::SmallVectorImpl<char>& RecoveryPath) {
    // Default implementation is no op.
    return false;
  }

  bool InterpreterCallbacks::LookupObject(LookupResult&, Scope*) {
    // Default implementation is no op.
    return false;
  }

  bool InterpreterCallbacks::LookupObject(const DeclContext*, DeclarationName) {
    // Default implementation is no op.
    return false;
  }

  bool InterpreterCallbacks::LookupObject(TagDecl*) {
    // Default implementation is no op.
    return false;
  }

  void InterpreterCallbacks::UpdateWithNewDecls(const DeclContext *DC,
                                                DeclarationName Name,
                                             llvm::ArrayRef<NamedDecl*> Decls) {
    if (m_ExternalSemaSource)
      m_ExternalSemaSource->UpdateWithNewDeclsFwd(DC, Name, Decls);
  }
} // end namespace cling

// TODO: Make the build system in the testsuite aware how to build that class
// and extract it out there again.
#include "DynamicLookup.h"
#include "cling/Utils/AST.h"

#include "clang/AST/ASTContext.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/Scope.h"
namespace cling {
namespace test {
  TestProxy* Tester = 0;

  extern "C" int printf(const char* fmt, ...);
  TestProxy::TestProxy(){}
  int TestProxy::Draw(){ return 12; }
  const char* TestProxy::getVersion(){ return "Interpreter.cpp"; }

  int TestProxy::Add10(int num) { return num + 10;}

  int TestProxy::Add(int a, int b) {
    return a + b;
  }

  void TestProxy::PrintString(std::string s) { printf("%s\n", s.c_str()); }

  bool TestProxy::PrintArray(int a[], size_t size) {
    for (unsigned i = 0; i < size; ++i)
      printf("%i", a[i]);

    printf("%s", "\n");

    return true;
  }

  void TestProxy::PrintArray(float a[][5], size_t size) {
    for (unsigned i = 0; i < size; ++i)
      for (unsigned j = 0; j < 5; ++j)
        printf("%i", (int)a[i][j]);

    printf("%s", "\n");
  }

  void TestProxy::PrintArray(int a[][4][5], size_t size) {
    for (unsigned i = 0; i < size; ++i)
      for (unsigned j = 0; j < 4; ++j)
        for (unsigned k = 0; k < 5; ++k)
          printf("%i", a[i][j][k]);

    printf("%s", "\n");
  }

  SymbolResolverCallback::SymbolResolverCallback(Interpreter* interp)
    : InterpreterCallbacks(interp), m_TesterDecl(0) {
    m_Interpreter->process("cling::test::Tester = new cling::test::TestProxy();");
  }

  SymbolResolverCallback::~SymbolResolverCallback() { }

  bool SymbolResolverCallback::LookupObject(LookupResult& R, Scope* S) {
    if (m_IsRuntime) {
      // Only for demo resolve all unknown objects to cling::test::Tester
      if (!m_TesterDecl) {
        clang::Sema& SemaR = m_Interpreter->getSema();
        clang::NamespaceDecl* NSD = utils::Lookup::Namespace(&SemaR, "cling");
        NSD = utils::Lookup::Namespace(&SemaR, "test", NSD);
        m_TesterDecl = utils::Lookup::Named(&SemaR, "Tester", NSD);
      }
      assert (m_TesterDecl && "Tester not found!");
      R.addDecl(m_TesterDecl);
      return true; // Tell clang to continue.
    }

    if (ShouldResolveAtRuntime(R, S)) {
      ASTContext& C = R.getSema().getASTContext();
      DeclContext* DC = 0;
      // For DeclContext-less scopes like if (dyn_expr) {}
      while (!DC) {
        DC = static_cast<DeclContext*>(S->getEntity());
        S = S->getParent();
      }
      DeclarationName Name = R.getLookupName();
      IdentifierInfo* II = Name.getAsIdentifierInfo();
      SourceLocation Loc = R.getNameLoc();
      VarDecl* Res = VarDecl::Create(C, DC, Loc, Loc, II, C.DependentTy,
                                     /*TypeSourceInfo*/0, SC_None);

      // Annotate the decl to give a hint in cling. FIXME: Current implementation
      // is a gross hack, because TClingCallbacks shouldn't know about
      // EvaluateTSynthesizer at all!
      SourceRange invalidRange;
      Res->addAttr(new (C) AnnotateAttr(invalidRange, C, "__ResolveAtRuntime", 0));
      R.addDecl(Res);
      DC->addDecl(Res);
      // Say that we can handle the situation. Clang should try to recover
      return true;
    }

    return false;
  }

  bool SymbolResolverCallback::ShouldResolveAtRuntime(LookupResult& R,
                                                      Scope* S) {

    if (R.getLookupKind() != Sema::LookupOrdinaryName)
      return false;

    if (R.isForRedeclaration())
      return false;

    if (!R.empty())
      return false;

    // FIXME: Figure out better way to handle:
    // C++ [basic.lookup.classref]p1:
    //   In a class member access expression (5.2.5), if the . or -> token is
    //   immediately followed by an identifier followed by a <, the
    //   identifier must be looked up to determine whether the < is the
    //   beginning of a template argument list (14.2) or a less-than operator.
    //   The identifier is first looked up in the class of the object
    //   expression. If the identifier is not found, it is then looked up in
    //   the context of the entire postfix-expression and shall name a class
    //   or function template.
    //
    // We want to ignore object(.|->)member<template>
    if (R.getSema().PP.LookAhead(0).getKind() == tok::less)
      // TODO: check for . or -> in the cached token stream
      return false;

    for (Scope* DepScope = S; DepScope; DepScope = DepScope->getParent()) {
      if (DeclContext* Ctx = static_cast<DeclContext*>(DepScope->getEntity())) {
        if (!Ctx->isDependentContext())
          // For now we support only the prompt.
          if (isa<FunctionDecl>(Ctx))
            return true;
      }
    }

    return false;
  }

} // end test
} // end cling
<commit_msg>Check if the AST reader is attached and if so attach also our listener.<commit_after>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Vassil Vassilev <vvasilev@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include "cling/Interpreter/InterpreterCallbacks.h"

#include "cling/Interpreter/Interpreter.h"

#include "clang/AST/ASTContext.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/Sema.h"
#include "clang/Serialization/ASTReader.h"
#include "clang/Serialization/ASTDeserializationListener.h"

using namespace clang;

namespace cling {

  ///\brief Translates 'interesting' for the interpreter
  /// ASTDeserializationListener events into interpreter callback.
  ///
  class InterpreterPPCallbacks : public PPCallbacks {
  private:
    cling::InterpreterCallbacks* m_Callbacks;
  public:
    InterpreterPPCallbacks(InterpreterCallbacks* C) : m_Callbacks(C) { }
    ~InterpreterPPCallbacks() { }

    virtual void InclusionDirective(clang::SourceLocation HashLoc,
                                    const clang::Token &IncludeTok,
                                    llvm::StringRef FileName,
                                    bool IsAngled,
                                    clang::CharSourceRange FilenameRange,
                                    const clang::FileEntry *File,
                                    llvm::StringRef SearchPath,
                                    llvm::StringRef RelativePath,
                                    const clang::Module *Imported) {
      m_Callbacks->InclusionDirective(HashLoc, IncludeTok, FileName,
                                      IsAngled, FilenameRange, File,
                                      SearchPath, RelativePath, Imported);
    }

    virtual bool FileNotFound(llvm::StringRef FileName,
                              llvm::SmallVectorImpl<char>& RecoveryPath) {
      if (m_Callbacks)
        return m_Callbacks->FileNotFound(FileName, RecoveryPath);

      // Returning true would mean that the preprocessor should try to recover.
      return false;
    }
  };

  ///\brief Translates 'interesting' for the interpreter
  /// ASTDeserializationListener events into interpreter callback.
  ///
  class InterpreterDeserializationListener : public ASTDeserializationListener {
  private:
    cling::InterpreterCallbacks* m_Callbacks;
  public:
    InterpreterDeserializationListener(InterpreterCallbacks* C)
      : m_Callbacks(C) {}

    virtual void DeclRead(serialization::DeclID, const Decl *D) {
      if (m_Callbacks)
        m_Callbacks->DeclDeserialized(D);
    }

    virtual void TypeRead(serialization::TypeIdx, QualType T) {
      if (m_Callbacks)
        m_Callbacks->TypeDeserialized(T.getTypePtr());
    }
  };

  ///\brief Translates 'interesting' for the interpreter ExternalSemaSource
  /// events into interpreter callbacks.
  ///
  class InterpreterExternalSemaSource : public clang::ExternalSemaSource {
  protected:
    ///\brief The interpreter callback which are subscribed for the events.
    ///
    /// Usually the callbacks is the owner of the class and the interpreter owns
    /// the callbacks so they can't be out of sync. Eg we notifying the wrong
    /// callback class.
    ///
    InterpreterCallbacks* m_Callbacks; // we don't own it.

    Sema* m_Sema; // we don't own // FIXME: once we remove ForgetSema delete.

  public:
    InterpreterExternalSemaSource(InterpreterCallbacks* C)
      : m_Callbacks(C), m_Sema(0) {}

    ~InterpreterExternalSemaSource() {
      // FIXME: Another gross hack due to the missing multiplexing AST external
      // source see Interpreter::setCallbacks.
      if (m_Sema) {
        ASTContext& C = m_Sema->getASTContext();
        // tell the owning ptr to not delete it, the callbacks will delete it.
        if (C.ExternalSource.get() == this)
          C.ExternalSource.resetWithoutRelease();
      }
    }

    virtual void InitializeSema(Sema& S) {
      m_Sema = &S;
    }

    virtual void ForgetSema() {
      m_Sema = 0;
    }

    InterpreterCallbacks* getCallbacks() const { return m_Callbacks; }

    /// \brief Provides last resort lookup for failed unqualified lookups.
    ///
    /// This gets translated into InterpreterCallback's call.
    ///
    ///\param[out] R The recovered symbol.
    ///\param[in] S The scope in which the lookup failed.
    ///
    ///\returns true if a suitable declaration is found.
    ///
    virtual bool LookupUnqualified(clang::LookupResult& R, clang::Scope* S) {
      if (m_Callbacks) {
        return m_Callbacks->LookupObject(R, S);
      }

      return false;
    }

    virtual bool FindExternalVisibleDeclsByName(const clang::DeclContext* DC,
                                                clang::DeclarationName Name) {
      if (m_Callbacks)
        return m_Callbacks->LookupObject(DC, Name);

      return false;
    }

    // Silence warning virtual function was hidden.
    using ExternalASTSource::CompleteType;
    virtual void CompleteType(TagDecl* Tag) {
      if (m_Callbacks)
        m_Callbacks->LookupObject(Tag);
    }

    void UpdateWithNewDeclsFwd(const DeclContext *DC, DeclarationName Name,
                               llvm::ArrayRef<NamedDecl*> Decls) {
      SetExternalVisibleDeclsForName(DC, Name, Decls);
    }
  };

  InterpreterCallbacks::InterpreterCallbacks(Interpreter* interp,
                             bool enableExternalSemaSourceCallbacks/* = false*/,
                        bool enableDeserializationListenerCallbacks/* = false*/,
                                             bool enablePPCallbacks/* = false*/)
    : m_Interpreter(interp), m_IsRuntime(false) {
    Sema& SemaRef = interp->getSema();
    ASTReader* Reader = m_Interpreter->getCI()->getModuleManager().get();
    ExternalSemaSource* externalSemaSrc = SemaRef.getExternalSource();
    if (enableExternalSemaSourceCallbacks)
      if (!externalSemaSrc || externalSemaSrc == Reader) {
        // If the ExternalSemaSource is the PCH reader we still need to insert
        // our listener.
        m_ExternalSemaSource.reset(new InterpreterExternalSemaSource(this));
        m_ExternalSemaSource->InitializeSema(SemaRef);
        m_Interpreter->getSema().addExternalSource(m_ExternalSemaSource.get());

        // FIXME: We should add a multiplexer in the ASTContext, too.
        llvm::IntrusiveRefCntPtr<ExternalASTSource>
          astContextExternalSource(SemaRef.getExternalSource());
        clang::ASTContext& Ctx = SemaRef.getASTContext();
        // FIXME: This is a gross hack. We must make multiplexer in the
        // astcontext or a derived class that extends what we need.
        Ctx.ExternalSource.resetWithoutRelease();//FIXME: make sure we delete it.
        Ctx.setExternalSource(astContextExternalSource);
    }

    if (enableDeserializationListenerCallbacks && Reader) {
      // FIXME: need to create a multiplexer if a DeserializationListener is
      // alreday present.
      m_DeserializationListener.
        reset(new InterpreterDeserializationListener(this));
      Reader->setDeserializationListener(m_DeserializationListener.get());
    }

    if (enablePPCallbacks) {
      m_PPCallbacks = new InterpreterPPCallbacks(this);
      Preprocessor& PP = m_Interpreter->getCI()->getPreprocessor();
      PP.addPPCallbacks(m_PPCallbacks);
    }
  }

  // pin the vtable here
  InterpreterCallbacks::~InterpreterCallbacks() {
    // FIXME: we have to remove the external source at destruction time. Needs
    // further tweaks of the patch in clang. This will be done later once the
    // patch is in clang's mainline.
  }

  void InterpreterCallbacks::SetIsRuntime(bool val) {
    m_IsRuntime = val;
  }

  ExternalSemaSource*
  InterpreterCallbacks::getInterpreterExternalSemaSource() const {
    return m_ExternalSemaSource.get();
  }

  ASTDeserializationListener*
  InterpreterCallbacks::getInterpreterDeserializationListener() const {
    return m_DeserializationListener.get();
  }

  bool InterpreterCallbacks::FileNotFound(llvm::StringRef FileName,
                                    llvm::SmallVectorImpl<char>& RecoveryPath) {
    // Default implementation is no op.
    return false;
  }

  bool InterpreterCallbacks::LookupObject(LookupResult&, Scope*) {
    // Default implementation is no op.
    return false;
  }

  bool InterpreterCallbacks::LookupObject(const DeclContext*, DeclarationName) {
    // Default implementation is no op.
    return false;
  }

  bool InterpreterCallbacks::LookupObject(TagDecl*) {
    // Default implementation is no op.
    return false;
  }

  void InterpreterCallbacks::UpdateWithNewDecls(const DeclContext *DC,
                                                DeclarationName Name,
                                             llvm::ArrayRef<NamedDecl*> Decls) {
    if (m_ExternalSemaSource)
      m_ExternalSemaSource->UpdateWithNewDeclsFwd(DC, Name, Decls);
  }
} // end namespace cling

// TODO: Make the build system in the testsuite aware how to build that class
// and extract it out there again.
#include "DynamicLookup.h"
#include "cling/Utils/AST.h"

#include "clang/AST/ASTContext.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/Scope.h"
namespace cling {
namespace test {
  TestProxy* Tester = 0;

  extern "C" int printf(const char* fmt, ...);
  TestProxy::TestProxy(){}
  int TestProxy::Draw(){ return 12; }
  const char* TestProxy::getVersion(){ return "Interpreter.cpp"; }

  int TestProxy::Add10(int num) { return num + 10;}

  int TestProxy::Add(int a, int b) {
    return a + b;
  }

  void TestProxy::PrintString(std::string s) { printf("%s\n", s.c_str()); }

  bool TestProxy::PrintArray(int a[], size_t size) {
    for (unsigned i = 0; i < size; ++i)
      printf("%i", a[i]);

    printf("%s", "\n");

    return true;
  }

  void TestProxy::PrintArray(float a[][5], size_t size) {
    for (unsigned i = 0; i < size; ++i)
      for (unsigned j = 0; j < 5; ++j)
        printf("%i", (int)a[i][j]);

    printf("%s", "\n");
  }

  void TestProxy::PrintArray(int a[][4][5], size_t size) {
    for (unsigned i = 0; i < size; ++i)
      for (unsigned j = 0; j < 4; ++j)
        for (unsigned k = 0; k < 5; ++k)
          printf("%i", a[i][j][k]);

    printf("%s", "\n");
  }

  SymbolResolverCallback::SymbolResolverCallback(Interpreter* interp)
    : InterpreterCallbacks(interp), m_TesterDecl(0) {
    m_Interpreter->process("cling::test::Tester = new cling::test::TestProxy();");
  }

  SymbolResolverCallback::~SymbolResolverCallback() { }

  bool SymbolResolverCallback::LookupObject(LookupResult& R, Scope* S) {
    if (m_IsRuntime) {
      // Only for demo resolve all unknown objects to cling::test::Tester
      if (!m_TesterDecl) {
        clang::Sema& SemaR = m_Interpreter->getSema();
        clang::NamespaceDecl* NSD = utils::Lookup::Namespace(&SemaR, "cling");
        NSD = utils::Lookup::Namespace(&SemaR, "test", NSD);
        m_TesterDecl = utils::Lookup::Named(&SemaR, "Tester", NSD);
      }
      assert (m_TesterDecl && "Tester not found!");
      R.addDecl(m_TesterDecl);
      return true; // Tell clang to continue.
    }

    if (ShouldResolveAtRuntime(R, S)) {
      ASTContext& C = R.getSema().getASTContext();
      DeclContext* DC = 0;
      // For DeclContext-less scopes like if (dyn_expr) {}
      while (!DC) {
        DC = static_cast<DeclContext*>(S->getEntity());
        S = S->getParent();
      }
      DeclarationName Name = R.getLookupName();
      IdentifierInfo* II = Name.getAsIdentifierInfo();
      SourceLocation Loc = R.getNameLoc();
      VarDecl* Res = VarDecl::Create(C, DC, Loc, Loc, II, C.DependentTy,
                                     /*TypeSourceInfo*/0, SC_None);

      // Annotate the decl to give a hint in cling. FIXME: Current implementation
      // is a gross hack, because TClingCallbacks shouldn't know about
      // EvaluateTSynthesizer at all!
      SourceRange invalidRange;
      Res->addAttr(new (C) AnnotateAttr(invalidRange, C, "__ResolveAtRuntime", 0));
      R.addDecl(Res);
      DC->addDecl(Res);
      // Say that we can handle the situation. Clang should try to recover
      return true;
    }

    return false;
  }

  bool SymbolResolverCallback::ShouldResolveAtRuntime(LookupResult& R,
                                                      Scope* S) {

    if (R.getLookupKind() != Sema::LookupOrdinaryName)
      return false;

    if (R.isForRedeclaration())
      return false;

    if (!R.empty())
      return false;

    // FIXME: Figure out better way to handle:
    // C++ [basic.lookup.classref]p1:
    //   In a class member access expression (5.2.5), if the . or -> token is
    //   immediately followed by an identifier followed by a <, the
    //   identifier must be looked up to determine whether the < is the
    //   beginning of a template argument list (14.2) or a less-than operator.
    //   The identifier is first looked up in the class of the object
    //   expression. If the identifier is not found, it is then looked up in
    //   the context of the entire postfix-expression and shall name a class
    //   or function template.
    //
    // We want to ignore object(.|->)member<template>
    if (R.getSema().PP.LookAhead(0).getKind() == tok::less)
      // TODO: check for . or -> in the cached token stream
      return false;

    for (Scope* DepScope = S; DepScope; DepScope = DepScope->getParent()) {
      if (DeclContext* Ctx = static_cast<DeclContext*>(DepScope->getEntity())) {
        if (!Ctx->isDependentContext())
          // For now we support only the prompt.
          if (isa<FunctionDecl>(Ctx))
            return true;
      }
    }

    return false;
  }

} // end test
} // end cling
<|endoftext|>


<commit_before>//
//  http_parse_routines.hpp - parsing routines for HTTP messages
//  part of the proto-server library
//
//  Copyright (c) 2015, 2016 Terry Seyler
//
//  Distributed under the MIT License
//  See accompanying file LICENSE.md
//

#ifndef HTTP_PARSE_ROUTINES_HPP_
#define HTTP_PARSE_ROUTINES_HPP_

#include <string>
#include <vector>
#include <core/data/proto_net_string_data.hpp>
#include <core/protocol/net_parse_routines.hpp>
#include <core/protocol/http/http_headers.hpp>

#define HTTP_PARSE_SUCCEEDED( r ) (r == http::http_parse_success)

namespace proto_net
{
	using namespace data;

	namespace protocol
	{
		namespace http
		{
			typedef std::vector<std::string> lines_t;
			typedef lines_t::iterator lines_t_iterator;
			typedef lines_t::const_iterator lines_t_const_iterator;

			typedef enum
			{
				http_parse_success,
				http_parse_internal_error,
				http_format_error,
				http_request_method_error,
				http_uri_error,
				http_version_error,
				http_header_field_error,
				http_status_code_error,
			} http_parse_result;

			// find the end of the line (beginning of \r\n) or return std::string::npos
			size_t find_crlf(const std::string &str, size_t pos);

			// find the line and return as out param.  Return start of next line
			size_t find_line(const std::string &str, std::string &line, size_t pos);

			// builds a collection of http header lines.  Returns number of lines
			size_t get_lines(const std::string &http, lines_t &lines);

			// builds a collection of header field lines
			size_t get_header_field_lines(const lines_t &http_lines, lines_t &header_field_lines);

			// return position of start of body
			size_t message_body_position(const proto_net_string_data& data);

			// tokenize routines
			size_t tokenize_http_line(const std::string line, matches_t &tokens);

			size_t tokenize_header_field(const std::string line, matches_t &tokens);

			// validate routines

			// validate request method
			http_parse_result validate_request_method(const std::string method);

			// validate request uri
			http_parse_result validate_request_uri(const std::string &uri, const std::string &method);

			// validate http version
			http_parse_result validate_http_version(const std::string &http_version);

			// validate request line
			http_parse_result validate_request_line(matches_t &tokens);

			// validate header field
			http_parse_result validate_header_field(matches_t &tokens, const std::string &field_name_pat);

			// validate header fields by category
			http_parse_result validate_header_fields(const lines_t &lines, const std::string &category,
													 http_header_fields &http_fields);

			// validate http headers
			http_parse_result validate_http_headers(const lines_t &lines, http_headers &headers);

			// validate status code
			http_parse_result validate_status_code(const std::string &status_code);

			// validate status line
			http_parse_result validate_status_line(matches_t &tokens);
		}
	}
}

#endif
<commit_msg>Added another rnumb for http request error.<commit_after>//
//  http_parse_routines.hpp - parsing routines for HTTP messages
//  part of the proto-server library
//
//  Copyright (c) 2015, 2016 Terry Seyler
//
//  Distributed under the MIT License
//  See accompanying file LICENSE.md
//

#ifndef HTTP_PARSE_ROUTINES_HPP_
#define HTTP_PARSE_ROUTINES_HPP_

#include <string>
#include <vector>
#include <core/data/proto_net_string_data.hpp>
#include <core/protocol/net_parse_routines.hpp>
#include <core/protocol/http/http_headers.hpp>

#define HTTP_PARSE_SUCCEEDED( r ) (r == http::http_parse_success)

namespace proto_net
{
	using namespace data;

	namespace protocol
	{
		namespace http
		{
			typedef std::vector<std::string> lines_t;
			typedef lines_t::iterator lines_t_iterator;
			typedef lines_t::const_iterator lines_t_const_iterator;

			typedef enum
			{
				http_uninitialized_error = -1,
				http_parse_success,
				http_parse_internal_error,
				http_format_error,
				http_request_method_error,
				http_uri_error,
				http_version_error,
				http_header_field_error,
				http_status_code_error,
			} http_parse_result;

			// find the end of the line (beginning of \r\n) or return std::string::npos
			size_t find_crlf(const std::string &str, size_t pos);

			// find the line and return as out param.  Return start of next line
			size_t find_line(const std::string &str, std::string &line, size_t pos);

			// builds a collection of http header lines.  Returns number of lines
			size_t get_lines(const std::string &http, lines_t &lines);

			// builds a collection of header field lines
			size_t get_header_field_lines(const lines_t &http_lines, lines_t &header_field_lines);

			// return position of start of body
			size_t message_body_position(const proto_net_string_data& data);

			// tokenize routines
			size_t tokenize_http_line(const std::string line, matches_t &tokens);

			size_t tokenize_header_field(const std::string line, matches_t &tokens);

			// validate routines

			// validate request method
			http_parse_result validate_request_method(const std::string method);

			// validate request uri
			http_parse_result validate_request_uri(const std::string &uri, const std::string &method);

			// validate http version
			http_parse_result validate_http_version(const std::string &http_version);

			// validate request line
			http_parse_result validate_request_line(matches_t &tokens);

			// validate header field
			http_parse_result validate_header_field(matches_t &tokens, const std::string &field_name_pat);

			// validate header fields by category
			http_parse_result validate_header_fields(const lines_t &lines, const std::string &category,
													 http_header_fields &http_fields);

			// validate http headers
			http_parse_result validate_http_headers(const lines_t &lines, http_headers &headers);

			// validate status code
			http_parse_result validate_status_code(const std::string &status_code);

			// validate status line
			http_parse_result validate_status_line(matches_t &tokens);
		}
	}
}

#endif
<|endoftext|>


<commit_before>//
//  download_manager.cpp
//  Cooloi_Assets_Downloader
//
//  Created by ESoragoto on 11/17/15.
//
//

#include "download_manager.hpp"
#include "assets_downloader.hpp"

#include "SimpleAudioEngine.h"

#include <iostream>
#include <string>
#include <fstream>
#include <regex>
#include <stdio.h>

#include "json/rapidjson.h"
#include "json/document.h"
#include "json/writer.h"
#include "json/stringbuffer.h"

using namespace cocos2d;
using namespace CocosDenshion;

#pragma mark - Initialization
DownloadManager::DownloadManager():
downloader_(nullptr),
stage_(DownloadStage ::kNull),
conf_(),
finished_(),
update_(),
now_downloading_(""),
now_number_(0)
{
} // DownloadManager

DownloadManager::~DownloadManager()
{
    if (downloader_)
        CC_SAFE_DELETE(downloader_);
} // ~DownloadManager

// on "init" you need to initialize your instance
bool DownloadManager::init()
{
    if ( !Scene::init() )
    {
        return false;
    }

    LoadConfig();

    InitDownloader();

    LoadUpdate();

    return true;
} // init

DownloadManager* DownloadManager::Create()
{
    auto d = new DownloadManager();
    if(d->init())
        return d;
    CC_SAFE_DELETE(d);
    return nullptr;
} // Create

void DownloadManager::update(float dt)
{
    if (downloader_->downloading()) return;

    unscheduleUpdate();

    switch (downloader()->status())
    {
//        case AssetsManager::ErrorCode::CREATE_FILE:
//        {
//            return;
//        }
//            break;

        case AssetsManager::ErrorCode::UNCOMPRESS:
        {
            set_stage(DownloadStage::kNull);
            return;
        }
            break;

        case AssetsManager::ErrorCode::NETWORK:
        {
            set_stage(DownloadStage::kNull);
            return;
        }
            break;

        default:
            break;
    }

    switch (stage())
    {
        case DownloadStage ::kLoadUpdate:
        {
            CheckUpdate();
        }
            break;

        case DownloadStage ::kGetUpdate:
        {
            GetUpdate();
        }
            break;

        default:
            break;
    }
} // update

#pragma mark - Member Function
#pragma mark -stage

int DownloadManager::LoadConfig()
{
    log("\nStage : Load config info.\n");
    set_stage(DownloadStage::kLoadConfig);
    auto ret = 0;
    std::string file_name = "";
//#if COCOS2D_DEBUG
//    file_name = "Cooloi_ASDL_DEBUG.conf";
////    file_name = "Cooloi_ASDL.conf";
//#else
//    file_name = "Cooloi_ASDL.conf";
//#endif
//    ret = ReadConf(file_name,
//                   conf_);

#if COCOS2D_DEBUG
    file_name = "Cooloi_ASDL_DEBUG.json";
    //    file_name = "Cooloi_ASDL.json";
#else
    file_name = "Cooloi_ASDL.json";
#endif
    ret = ReadConfigFromJson(file_name,
                             conf_);

    if (0 != ret)
    {
        set_stage(DownloadStage::kNull);
    }
    return ret;
} // LoadConfig

int DownloadManager::InitDownloader()
{
    log("\nStage : Initialization Downloader.\n");
    set_stage(DownloadStage::kInitDownloader);
    downloader_ = new AssetsDownloader(conf_["URL"],
                                       conf_["VER"],
                                       conf_["DIR"],
                                       std::stoi(conf_["TRY"]));
    downloader_->Init();
    return 0;
} // InitDownloader

int DownloadManager::LoadUpdate()
{
    log("\nStage : Download update info.\n");
    set_stage(DownloadStage::kLoadUpdate);
    Download(conf_["URL"]);
    return 0;
} // LoadUpdate

int DownloadManager::CheckUpdate()
{
    log("\nStage : Check update info.\n");
    set_stage(DownloadStage::kCheckUpdate);
    auto ret = 0;
    if ("" != now_downloading_) push_finished(now_downloading());
//    ret = ReadConf(conf_["NAME"], pkg_map_);
//    ret = ReadConf(conf_["LOCAL_NAME"], loc_map_);

    ret = ReadConfigFromJson(conf_["NAME"], pkg_map_);
    ret = ReadConfigFromJson(conf_["LOCAL_NAME"], loc_map_);

    for (auto p : pkg_map())
    {
        if (p.second != loc_map_[p.first])
        {
            push_update(p.first);
        }
    }

    if (update().empty())
    {
        set_stage(DownloadStage::kFinished);
    }
    else
    {
        log("New package find!");
//        GetUpdate();
    }
    return ret;
} // CheckUpdate

int DownloadManager::GetUpdate()
{
    log("\nStage : Get update package.\n");
    set_stage(DownloadStage::kGetUpdate);
    auto ret = 0;
    if ("" != now_downloading_) push_finished(now_downloading());

    for (auto u : update())
    {
        auto jump = false;
        for (auto f : finished())
        {
            if (u == f)
            {
                jump = true;
                break;
            }
        }
        if (jump) continue;

        set_now_downloading(u);
        Download(conf().at("SER") + pkg_map_[u]);
        break;
    }

    if (update().size() == finished().size())
    {
        std::string content = "#loacl list\n";
        for (auto p : pkg_map())
        {
            content += (p.first + " = " + p.second + "\n");
        }
        WriteFile(conf_["LOCAL_NAME"], content);
        auto s = FileUtils::getInstance()->getStringFromFile(conf_["LOCAL_NAME"]);
        log("%s", s.c_str());
        set_stage(DownloadStage::kFinished);
    }

    return ret;
} // GetUpdate

void DownloadManager::Close()
{
    Director::getInstance()->end();

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    exit(0);
#endif
} // Close

#pragma mark -other

int DownloadManager::Download(const std::string pkg_url)
{
    log("Request to download resource : %s", pkg_url.c_str());
    downloader_->Download(pkg_url);

    scheduleUpdate();
    return 0;
} // Download

int DownloadManager::ReadConf(const std::string file_name,
                              std::map<std::string, std::string> &conf_map)
{
    log("Read config file : %s", file_name.c_str());
    std::string path_with_file = "";
    FindPathWithFile(file_name, path_with_file);
    if ("" == path_with_file)
    {
        WriteFile(file_name, "");
        return 1;
    }

    auto str = FileUtils::getInstance()->getStringFromFile(file_name);
    log("getStringFromFile\n%s",str.c_str());

    std::ifstream in_file(path_with_file);
    if(in_file.fail())
        return 1001;

    std::string str_by_line = "";
    while (std::getline(in_file, str_by_line))
    {
        std::string arg;
        std::string value;
        ConfRegex(str_by_line, arg, value);
        conf_map[arg] = value;
    }
    return 0;
} // ReadConf

int DownloadManager::ConfRegex(const std::string str,
                               std::string &arg,
                               std::string &value)
{
    log("Regex line : %s", str.c_str());
    std::regex rgx("^(\\w+)\\s*\\=\\s*([^\\s]+)$");
    std::smatch match;

    if (std::regex_search(str.begin(), str.end(), match, rgx))
    {
        for(auto q : match)
        {
            log("\t%s", q.str().c_str());
        }
        log("----");
        arg = match[1].str();
        value = match[2].str();
    }
    return 0;
} // ConfRegex

int DownloadManager::ReadConfigFromJson(const std::string file_name,
                                        std::map<std::string, std::string> &conf_map)
{
    std::string file_with_path = "";
    FindPathWithFile(file_name, file_with_path);
    auto str = FileUtils::getInstance()->getStringFromFile(file_with_path.c_str());
    log("getStringFromFile : %s", str.c_str());
    if ("" == str)
    {
        set_stage(DownloadStage::kFileNotFound);
        return 1404;
    }
    rapidjson::Document d;
    d.Parse<0>(str.c_str());
    for (auto iter = d.MemberBegin() ; iter != d.MemberEnd() ; iter++)
    {
        log("read config name is %s. value is %s", iter->name.GetString(), iter->value.GetString());
        conf_map[iter->name.GetString()] = iter->value.GetString();
    }
    return 0;
}

int DownloadManager::WriteConfigToJson(const std::string file_name,
                                       std::map<std::string, std::string> &conf_map)
{
    std::string file_with_path = "";
    FindPathWithFile(file_name, file_with_path);

    rapidjson::Document d;
    d.SetObject();
    for(auto c : conf_map)
    {
        log("write config name is %s, value is %s", c.first.c_str(), c.second.c_str());
        rapidjson::Value name(rapidjson::kStringType);
        name.SetString(c.first.c_str(), (int)c.first.length());

        rapidjson::Value value(rapidjson::kStringType);
        value.SetString(c.second.c_str(), (int)c.second.length());

        d.AddMember(name, value, d.GetAllocator());
    }

    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> write(buffer);
    d.Accept(write);

    log("now write config is %s", buffer.GetString());

    if ("" == file_with_path)
    {
        file_with_path = FileUtils::getInstance()->getWritablePath() + file_name;
    }

    FILE* file = fopen(file_with_path.c_str(), "wb");
    if (file)
    {
        fputs(buffer.GetString(), file);
        fclose(file);
    }
    return 0;
}

int DownloadManager::ReadFile(const std::string file_name,
                              std::string &content)
{
    log("Preparing Read file : %s", file_name.c_str());
    std::string file_with_path = "";
    FindPathWithFile(file_name, file_with_path);
    if ("" == file_with_path)
        return 1404;

    log("Full path: %s", file_with_path.c_str());
    auto file = FileUtils::getInstance()->getStringFromFile(file_with_path);

    if ("" == file)
    {
        std::ifstream infile(file_with_path);

        if (infile.fail())
        {
            log("Open file fail, file name: %s", file_name.c_str());
            return 1001;
        }

        std::string str((std::istreambuf_iterator<char>(infile)),
                        std::istreambuf_iterator<char>());
        file = str.c_str();
        infile.close();
    }

    log("open file:\n----\n%s\n----", file.c_str());
    content = file;
    return 0;
} // ReadFile

int DownloadManager::WriteFile(const std::string file_name,
                               const std::string content)
{
    log("Preparing write file : %s", file_name.c_str());
    std::string file_to_write = "";
    FindPathWithFile(file_name, file_to_write);
    if ("" == file_to_write)
    {
        file_to_write = FileUtils::getInstance()->getWritablePath();
//        file_to_write += conf_["Dir"];
        file_to_write += file_name;
    }

    log("Write path : %s", file_to_write.c_str());
    std::ofstream outfile;
    outfile.open(file_to_write);
    if (outfile.fail())
    {
        log("Open file fail, file name: %s", file_name.c_str());
        return 1001;
    }
    std::string str = "#" + file_name + "\n" + content;
    outfile << str;
    log("write file with fstream : \n----\n%s\n----", str.c_str());
    outfile.close();
    return 0;
} // WriteFile

int DownloadManager::AppendFile(const std::string file_name,
                                const std::string content)
{
    auto ret = 0;
    std::string path_with_file = "";
    FindPathWithFile(file_name, path_with_file);

    if ("" == path_with_file)
    {
        return 1404;
    }
    log("Full path: %s", path_with_file.c_str());

    std::string front_content = "";
    ret = ReadFile(file_name,
                   front_content);
    if (0 != ret)
        return ret;

    ret = WriteFile(file_name, front_content + "\n" + content);
    return ret;
} // AppendFile

int DownloadManager::FindPathWithFile(const std::string file_name,
                                      std::string &path_with_file)
{
    auto path = FileUtils::getInstance()->fullPathForFilename(file_name);
    if ("" == path)
    {
        auto temp_name = FileUtils::getInstance()->getWritablePath() + file_name;
        path = FileUtils::getInstance()->fullPathForFilename(temp_name);
        if ("" == path) log("File not exist!");
    }
    if ("" != path)
        log("Find file with : %s", path.c_str());
    path_with_file = path;
    return 0;
} // FindPathWithFile
<commit_msg>kFileNotFound2<commit_after>//
//  download_manager.cpp
//  Cooloi_Assets_Downloader
//
//  Created by ESoragoto on 11/17/15.
//
//

#include "download_manager.hpp"
#include "assets_downloader.hpp"

#include "SimpleAudioEngine.h"

#include <iostream>
#include <string>
#include <fstream>
#include <regex>
#include <stdio.h>

#include "json/rapidjson.h"
#include "json/document.h"
#include "json/writer.h"
#include "json/stringbuffer.h"

using namespace cocos2d;
using namespace CocosDenshion;

#pragma mark - Initialization
DownloadManager::DownloadManager():
downloader_(nullptr),
stage_(DownloadStage ::kNull),
conf_(),
finished_(),
update_(),
now_downloading_(""),
now_number_(0)
{
} // DownloadManager

DownloadManager::~DownloadManager()
{
    if (downloader_)
        CC_SAFE_DELETE(downloader_);
} // ~DownloadManager

// on "init" you need to initialize your instance
bool DownloadManager::init()
{
    if ( !Scene::init() )
    {
        return false;
    }

    LoadConfig();

    InitDownloader();

    LoadUpdate();

    return true;
} // init

DownloadManager* DownloadManager::Create()
{
    auto d = new DownloadManager();
    if(d->init())
        return d;
    CC_SAFE_DELETE(d);
    return nullptr;
} // Create

void DownloadManager::update(float dt)
{
    if (downloader_->downloading()) return;

    unscheduleUpdate();

    switch (downloader()->status())
    {
//        case AssetsManager::ErrorCode::CREATE_FILE:
//        {
//            return;
//        }
//            break;

        case AssetsManager::ErrorCode::UNCOMPRESS:
        {
            set_stage(DownloadStage::kNull);
            return;
        }
            break;

        case AssetsManager::ErrorCode::NETWORK:
        {
            set_stage(DownloadStage::kNull);
            return;
        }
            break;

        default:
            break;
    }

    switch (stage())
    {
        case DownloadStage ::kLoadUpdate:
        {
            CheckUpdate();
        }
            break;

        case DownloadStage ::kGetUpdate:
        {
            GetUpdate();
        }
            break;

        default:
            break;
    }
} // update

#pragma mark - Member Function
#pragma mark -stage

int DownloadManager::LoadConfig()
{
    log("\nStage : Load config info.\n");
    set_stage(DownloadStage::kLoadConfig);
    auto ret = 0;
    std::string file_name = "";
//#if COCOS2D_DEBUG
//    file_name = "Cooloi_ASDL_DEBUG.conf";
////    file_name = "Cooloi_ASDL.conf";
//#else
//    file_name = "Cooloi_ASDL.conf";
//#endif
//    ret = ReadConf(file_name,
//                   conf_);

#if COCOS2D_DEBUG
    file_name = "Cooloi_ASDL_DEBUG.json";
    //    file_name = "Cooloi_ASDL.json";
#else
    file_name = "Cooloi_ASDL.json";
#endif
    ret = ReadConfigFromJson(file_name,
                             conf_);

    if (0 != ret)
    {
        set_stage(DownloadStage::kNull);
    }
    return ret;
} // LoadConfig

int DownloadManager::InitDownloader()
{
    log("\nStage : Initialization Downloader.\n");
    set_stage(DownloadStage::kInitDownloader);
    downloader_ = new AssetsDownloader(conf_["URL"],
                                       conf_["VER"],
                                       conf_["DIR"],
                                       std::stoi(conf_["TRY"]));
    downloader_->Init();
    return 0;
} // InitDownloader

int DownloadManager::LoadUpdate()
{
    log("\nStage : Download update info.\n");
    set_stage(DownloadStage::kLoadUpdate);
    Download(conf_["URL"]);
    return 0;
} // LoadUpdate

int DownloadManager::CheckUpdate()
{
    log("\nStage : Check update info.\n");
    set_stage(DownloadStage::kCheckUpdate);
    auto ret = 0;
    if ("" != now_downloading_) push_finished(now_downloading());
//    ret = ReadConf(conf_["NAME"], pkg_map_);
//    ret = ReadConf(conf_["LOCAL_NAME"], loc_map_);

    ret = ReadConfigFromJson(conf_["NAME"], pkg_map_);
    ret = ReadConfigFromJson(conf_["LOCAL_NAME"], loc_map_);

    for (auto p : pkg_map())
    {
        if (p.second != loc_map_[p.first])
        {
            push_update(p.first);
        }
    }

    if (update().empty())
    {
        set_stage(DownloadStage::kFinished);
    }
    else
    {
        log("New package find!");
//        GetUpdate();
    }
    return ret;
} // CheckUpdate

int DownloadManager::GetUpdate()
{
    log("\nStage : Get update package.\n");
    set_stage(DownloadStage::kGetUpdate);
    auto ret = 0;
    if ("" != now_downloading_) push_finished(now_downloading());

    for (auto u : update())
    {
        auto jump = false;
        for (auto f : finished())
        {
            if (u == f)
            {
                jump = true;
                break;
            }
        }
        if (jump) continue;

        set_now_downloading(u);
        Download(conf().at("SER") + pkg_map_[u]);
        break;
    }

    if (update().size() == finished().size())
    {
        std::string content = "#loacl list\n";
        for (auto p : pkg_map())
        {
            content += (p.first + " = " + p.second + "\n");
        }
        WriteFile(conf_["LOCAL_NAME"], content);
        auto s = FileUtils::getInstance()->getStringFromFile(conf_["LOCAL_NAME"]);
        log("%s", s.c_str());
        set_stage(DownloadStage::kFinished);
    }

    return ret;
} // GetUpdate

void DownloadManager::Close()
{
    Director::getInstance()->end();

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    exit(0);
#endif
} // Close

#pragma mark -other

int DownloadManager::Download(const std::string pkg_url)
{
    log("Request to download resource : %s", pkg_url.c_str());
    downloader_->Download(pkg_url);

    scheduleUpdate();
    return 0;
} // Download

int DownloadManager::ReadConf(const std::string file_name,
                              std::map<std::string, std::string> &conf_map)
{
    log("Read config file : %s", file_name.c_str());
    std::string path_with_file = "";
    FindPathWithFile(file_name, path_with_file);
    if ("" == path_with_file)
    {
        WriteFile(file_name, "");
        return 1;
    }

    auto str = FileUtils::getInstance()->getStringFromFile(file_name);
    log("getStringFromFile\n%s",str.c_str());

    std::ifstream in_file(path_with_file);
    if(in_file.fail())
        return 1001;

    std::string str_by_line = "";
    while (std::getline(in_file, str_by_line))
    {
        std::string arg;
        std::string value;
        ConfRegex(str_by_line, arg, value);
        conf_map[arg] = value;
    }
    return 0;
} // ReadConf

int DownloadManager::ConfRegex(const std::string str,
                               std::string &arg,
                               std::string &value)
{
    log("Regex line : %s", str.c_str());
    std::regex rgx("^(\\w+)\\s*\\=\\s*([^\\s]+)$");
    std::smatch match;

    if (std::regex_search(str.begin(), str.end(), match, rgx))
    {
        for(auto q : match)
        {
            log("\t%s", q.str().c_str());
        }
        log("----");
        arg = match[1].str();
        value = match[2].str();
    }
    return 0;
} // ConfRegex

int DownloadManager::ReadConfigFromJson(const std::string file_name,
                                        std::map<std::string, std::string> &conf_map)
{
    std::string file_with_path = "";
    FindPathWithFile(file_name, file_with_path);
    auto str = FileUtils::getInstance()->getStringFromFile(file_with_path.c_str());
    log("getStringFromFile : %s", str.c_str());
    if ("" == str)
    {
        set_stage(DownloadStage::kFileNotFound);
        return 1404;
    }
    rapidjson::Document d;
    d.Parse<0>(str.c_str());
    if(!d.IsObject())
    {
        set_stage(DownloadStage::kFileNotFound);
        return 1404;
    }
    for (auto iter = d.MemberBegin() ; iter != d.MemberEnd() ; iter++)
    {
        log("read config name is %s. value is %s", iter->name.GetString(), iter->value.GetString());
        conf_map[iter->name.GetString()] = iter->value.GetString();
    }
    return 0;
}

int DownloadManager::WriteConfigToJson(const std::string file_name,
                                       std::map<std::string, std::string> &conf_map)
{
    std::string file_with_path = "";
    FindPathWithFile(file_name, file_with_path);

    rapidjson::Document d;
    d.SetObject();
    for(auto c : conf_map)
    {
        log("write config name is %s, value is %s", c.first.c_str(), c.second.c_str());
        rapidjson::Value name(rapidjson::kStringType);
        name.SetString(c.first.c_str(), (int)c.first.length());

        rapidjson::Value value(rapidjson::kStringType);
        value.SetString(c.second.c_str(), (int)c.second.length());

        d.AddMember(name, value, d.GetAllocator());
    }

    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> write(buffer);
    d.Accept(write);

    log("now write config is %s", buffer.GetString());

    if ("" == file_with_path)
    {
        file_with_path = FileUtils::getInstance()->getWritablePath() + file_name;
    }

    FILE* file = fopen(file_with_path.c_str(), "wb");
    if (file)
    {
        fputs(buffer.GetString(), file);
        fclose(file);
    }
    return 0;
}

int DownloadManager::ReadFile(const std::string file_name,
                              std::string &content)
{
    log("Preparing Read file : %s", file_name.c_str());
    std::string file_with_path = "";
    FindPathWithFile(file_name, file_with_path);
    if ("" == file_with_path)
        return 1404;

    log("Full path: %s", file_with_path.c_str());
    auto file = FileUtils::getInstance()->getStringFromFile(file_with_path);

    if ("" == file)
    {
        std::ifstream infile(file_with_path);

        if (infile.fail())
        {
            log("Open file fail, file name: %s", file_name.c_str());
            return 1001;
        }

        std::string str((std::istreambuf_iterator<char>(infile)),
                        std::istreambuf_iterator<char>());
        file = str.c_str();
        infile.close();
    }

    log("open file:\n----\n%s\n----", file.c_str());
    content = file;
    return 0;
} // ReadFile

int DownloadManager::WriteFile(const std::string file_name,
                               const std::string content)
{
    log("Preparing write file : %s", file_name.c_str());
    std::string file_to_write = "";
    FindPathWithFile(file_name, file_to_write);
    if ("" == file_to_write)
    {
        file_to_write = FileUtils::getInstance()->getWritablePath();
//        file_to_write += conf_["Dir"];
        file_to_write += file_name;
    }

    log("Write path : %s", file_to_write.c_str());
    std::ofstream outfile;
    outfile.open(file_to_write);
    if (outfile.fail())
    {
        log("Open file fail, file name: %s", file_name.c_str());
        return 1001;
    }
    std::string str = "#" + file_name + "\n" + content;
    outfile << str;
    log("write file with fstream : \n----\n%s\n----", str.c_str());
    outfile.close();
    return 0;
} // WriteFile

int DownloadManager::AppendFile(const std::string file_name,
                                const std::string content)
{
    auto ret = 0;
    std::string path_with_file = "";
    FindPathWithFile(file_name, path_with_file);

    if ("" == path_with_file)
    {
        return 1404;
    }
    log("Full path: %s", path_with_file.c_str());

    std::string front_content = "";
    ret = ReadFile(file_name,
                   front_content);
    if (0 != ret)
        return ret;

    ret = WriteFile(file_name, front_content + "\n" + content);
    return ret;
} // AppendFile

int DownloadManager::FindPathWithFile(const std::string file_name,
                                      std::string &path_with_file)
{
    auto path = FileUtils::getInstance()->fullPathForFilename(file_name);
    if ("" == path)
    {
        auto temp_name = FileUtils::getInstance()->getWritablePath() + file_name;
        path = FileUtils::getInstance()->fullPathForFilename(temp_name);
        if ("" == path) log("File not exist!");
    }
    if ("" != path)
        log("Find file with : %s", path.c_str());
    path_with_file = path;
    return 0;
} // FindPathWithFile
<|endoftext|>