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

#include "src/profiling/common/unwind_support.h"

#include <inttypes.h>

#include <procinfo/process_map.h>
#include <unwindstack/Maps.h>
#include <unwindstack/Memory.h>

#include "perfetto/ext/base/file_utils.h"

namespace perfetto {
namespace profiling {

StackOverlayMemory::StackOverlayMemory(std::shared_ptr<unwindstack::Memory> mem,
                                       uint64_t sp,
                                       const uint8_t* stack,
                                       size_t size)
    : mem_(std::move(mem)), sp_(sp), stack_end_(sp + size), stack_(stack) {}

size_t StackOverlayMemory::Read(uint64_t addr, void* dst, size_t size) {
  if (addr >= sp_ && addr + size <= stack_end_ && addr + size > sp_) {
    size_t offset = static_cast<size_t>(addr - sp_);
    memcpy(dst, stack_ + offset, size);
    return size;
  }

  return mem_->Read(addr, dst, size);
}

FDMemory::FDMemory(base::ScopedFile mem_fd) : mem_fd_(std::move(mem_fd)) {}

size_t FDMemory::Read(uint64_t addr, void* dst, size_t size) {
  ssize_t rd = pread64(*mem_fd_, dst, size, static_cast<off64_t>(addr));
  if (rd == -1) {
    PERFETTO_DPLOG("read of %zu at offset %" PRIu64, size, addr);
    return 0;
  }
  return static_cast<size_t>(rd);
}

FDMaps::FDMaps(base::ScopedFile fd) : fd_(std::move(fd)) {}

bool FDMaps::Parse() {
  // If the process has already exited, lseek or ReadFileDescriptor will
  // return false.
  if (lseek(*fd_, 0, SEEK_SET) == -1)
    return false;

  std::string content;
  if (!base::ReadFileDescriptor(*fd_, &content))
    return false;

  unwindstack::MapInfo* prev_map = nullptr;
  unwindstack::MapInfo* prev_real_map = nullptr;
  return android::procinfo::ReadMapFileContent(
      &content[0], [&](const android::procinfo::MapInfo& mapinfo) {
        // Mark a device map in /dev/ and not in /dev/ashmem/ specially.
        auto flags = mapinfo.flags;
        if (strncmp(mapinfo.name.c_str(), "/dev/", 5) == 0 &&
            strncmp(mapinfo.name.c_str() + 5, "ashmem/", 7) != 0) {
          flags |= unwindstack::MAPS_FLAGS_DEVICE_MAP;
        }
        maps_.emplace_back(new unwindstack::MapInfo(
            prev_map, prev_real_map, mapinfo.start, mapinfo.end, mapinfo.pgoff,
            flags, mapinfo.name));
        prev_map = maps_.back().get();
        if (!prev_map->IsBlank()) {
          prev_real_map = prev_map;
        }
      });
}

void FDMaps::Reset() {
  maps_.clear();
}

UnwindingMetadata::UnwindingMetadata(base::ScopedFile maps_fd,
                                     base::ScopedFile mem_fd)
    : fd_maps(std::move(maps_fd)),
      fd_mem(std::make_shared<FDMemory>(std::move(mem_fd))) {
  if (!fd_maps.Parse())
    PERFETTO_DLOG("Failed initial maps parse");
}

void UnwindingMetadata::ReparseMaps() {
  reparses++;
  fd_maps.Reset();
  fd_maps.Parse();
#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
  jit_debug.reset();
  dex_files.reset();
#endif
}

#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
unwindstack::JitDebug* UnwindingMetadata::GetJitDebug(unwindstack::ArchEnum arch) {
  if (jit_debug.get() == nullptr) {
    std::vector<std::string> search_libs{"libart.so", "libartd.so"};
    jit_debug = unwindstack::CreateJitDebug(arch, fd_mem, search_libs);
  }
  return jit_debug.get();
}

unwindstack::DexFiles* UnwindingMetadata::GetDexFiles(unwindstack::ArchEnum arch) {
  if (dex_files.get() == nullptr) {
    std::vector<std::string> search_libs{"libart.so", "libartd.so"};
    dex_files = unwindstack::CreateDexFiles(arch, fd_mem, search_libs);
  }
  return dex_files.get();
}
#endif

const std::string& UnwindingMetadata::GetBuildId(
    const unwindstack::FrameData& frame) {
  if (!frame.map_name.empty()) {
    unwindstack::MapInfo* map_info = fd_maps.Find(frame.pc);
    if (map_info)
      return map_info->GetBuildID();
  }

  return empty_string_;
}

std::string StringifyLibUnwindstackError(unwindstack::ErrorCode e) {
  switch (e) {
    case unwindstack::ERROR_NONE:
      return "NONE";
    case unwindstack::ERROR_MEMORY_INVALID:
      return "MEMORY_INVALID";
    case unwindstack::ERROR_UNWIND_INFO:
      return "UNWIND_INFO";
    case unwindstack::ERROR_UNSUPPORTED:
      return "UNSUPPORTED";
    case unwindstack::ERROR_INVALID_MAP:
      return "INVALID_MAP";
    case unwindstack::ERROR_MAX_FRAMES_EXCEEDED:
      return "MAX_FRAME_EXCEEDED";
    case unwindstack::ERROR_REPEATED_FRAME:
      return "REPEATED_FRAME";
    case unwindstack::ERROR_INVALID_ELF:
      return "INVALID_ELF";
    case unwindstack::ERROR_SYSTEM_CALL:
      return "SYSTEM_CALL";
    case unwindstack::ERROR_THREAD_DOES_NOT_EXIST:
      return "THREAD_DOES_NOT_EXIST";
    case unwindstack::ERROR_THREAD_TIMEOUT:
      return "THREAD_TIMEOUT";
  }
}

}  // namespace profiling
}  // namespace perfetto
<commit_msg>profilers: always log cross-process read errors<commit_after>/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "src/profiling/common/unwind_support.h"

#include <inttypes.h>

#include <procinfo/process_map.h>
#include <unwindstack/Maps.h>
#include <unwindstack/Memory.h>

#include "perfetto/ext/base/file_utils.h"

namespace perfetto {
namespace profiling {

StackOverlayMemory::StackOverlayMemory(std::shared_ptr<unwindstack::Memory> mem,
                                       uint64_t sp,
                                       const uint8_t* stack,
                                       size_t size)
    : mem_(std::move(mem)), sp_(sp), stack_end_(sp + size), stack_(stack) {}

size_t StackOverlayMemory::Read(uint64_t addr, void* dst, size_t size) {
  if (addr >= sp_ && addr + size <= stack_end_ && addr + size > sp_) {
    size_t offset = static_cast<size_t>(addr - sp_);
    memcpy(dst, stack_ + offset, size);
    return size;
  }

  return mem_->Read(addr, dst, size);
}

FDMemory::FDMemory(base::ScopedFile mem_fd) : mem_fd_(std::move(mem_fd)) {}

size_t FDMemory::Read(uint64_t addr, void* dst, size_t size) {
  ssize_t rd = pread64(*mem_fd_, dst, size, static_cast<off64_t>(addr));
  if (PERFETTO_UNLIKELY(rd == -1)) {
    PERFETTO_PLOG("Failed remote pread of %zu bytes at address %" PRIx64, size,
                  addr);
    return 0;
  }
  return static_cast<size_t>(rd);
}

FDMaps::FDMaps(base::ScopedFile fd) : fd_(std::move(fd)) {}

bool FDMaps::Parse() {
  // If the process has already exited, lseek or ReadFileDescriptor will
  // return false.
  if (lseek(*fd_, 0, SEEK_SET) == -1)
    return false;

  std::string content;
  if (!base::ReadFileDescriptor(*fd_, &content))
    return false;

  unwindstack::MapInfo* prev_map = nullptr;
  unwindstack::MapInfo* prev_real_map = nullptr;
  return android::procinfo::ReadMapFileContent(
      &content[0], [&](const android::procinfo::MapInfo& mapinfo) {
        // Mark a device map in /dev/ and not in /dev/ashmem/ specially.
        auto flags = mapinfo.flags;
        if (strncmp(mapinfo.name.c_str(), "/dev/", 5) == 0 &&
            strncmp(mapinfo.name.c_str() + 5, "ashmem/", 7) != 0) {
          flags |= unwindstack::MAPS_FLAGS_DEVICE_MAP;
        }
        maps_.emplace_back(new unwindstack::MapInfo(
            prev_map, prev_real_map, mapinfo.start, mapinfo.end, mapinfo.pgoff,
            flags, mapinfo.name));
        prev_map = maps_.back().get();
        if (!prev_map->IsBlank()) {
          prev_real_map = prev_map;
        }
      });
}

void FDMaps::Reset() {
  maps_.clear();
}

UnwindingMetadata::UnwindingMetadata(base::ScopedFile maps_fd,
                                     base::ScopedFile mem_fd)
    : fd_maps(std::move(maps_fd)),
      fd_mem(std::make_shared<FDMemory>(std::move(mem_fd))) {
  if (!fd_maps.Parse())
    PERFETTO_DLOG("Failed initial maps parse");
}

void UnwindingMetadata::ReparseMaps() {
  reparses++;
  fd_maps.Reset();
  fd_maps.Parse();
#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
  jit_debug.reset();
  dex_files.reset();
#endif
}

#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
unwindstack::JitDebug* UnwindingMetadata::GetJitDebug(unwindstack::ArchEnum arch) {
  if (jit_debug.get() == nullptr) {
    std::vector<std::string> search_libs{"libart.so", "libartd.so"};
    jit_debug = unwindstack::CreateJitDebug(arch, fd_mem, search_libs);
  }
  return jit_debug.get();
}

unwindstack::DexFiles* UnwindingMetadata::GetDexFiles(unwindstack::ArchEnum arch) {
  if (dex_files.get() == nullptr) {
    std::vector<std::string> search_libs{"libart.so", "libartd.so"};
    dex_files = unwindstack::CreateDexFiles(arch, fd_mem, search_libs);
  }
  return dex_files.get();
}
#endif

const std::string& UnwindingMetadata::GetBuildId(
    const unwindstack::FrameData& frame) {
  if (!frame.map_name.empty()) {
    unwindstack::MapInfo* map_info = fd_maps.Find(frame.pc);
    if (map_info)
      return map_info->GetBuildID();
  }

  return empty_string_;
}

std::string StringifyLibUnwindstackError(unwindstack::ErrorCode e) {
  switch (e) {
    case unwindstack::ERROR_NONE:
      return "NONE";
    case unwindstack::ERROR_MEMORY_INVALID:
      return "MEMORY_INVALID";
    case unwindstack::ERROR_UNWIND_INFO:
      return "UNWIND_INFO";
    case unwindstack::ERROR_UNSUPPORTED:
      return "UNSUPPORTED";
    case unwindstack::ERROR_INVALID_MAP:
      return "INVALID_MAP";
    case unwindstack::ERROR_MAX_FRAMES_EXCEEDED:
      return "MAX_FRAME_EXCEEDED";
    case unwindstack::ERROR_REPEATED_FRAME:
      return "REPEATED_FRAME";
    case unwindstack::ERROR_INVALID_ELF:
      return "INVALID_ELF";
    case unwindstack::ERROR_SYSTEM_CALL:
      return "SYSTEM_CALL";
    case unwindstack::ERROR_THREAD_DOES_NOT_EXIST:
      return "THREAD_DOES_NOT_EXIST";
    case unwindstack::ERROR_THREAD_TIMEOUT:
      return "THREAD_TIMEOUT";
  }
}

}  // namespace profiling
}  // namespace perfetto
<|endoftext|>


<commit_before>#include "IRVisitor.h"
#include "IR.h"

namespace Halide {
namespace Internal {

IRVisitor::~IRVisitor() {
}

void IRVisitor::visit(const IntImm *) {
}

void IRVisitor::visit(const FloatImm *) {
}

void IRVisitor::visit(const StringImm *) {
}

void IRVisitor::visit(const Cast *op) {
    op->value.accept(this);
}

void IRVisitor::visit(const Variable *) {
}

void IRVisitor::visit(const Add *op) {
    op->a.accept(this);
    op->b.accept(this);
}

void IRVisitor::visit(const Sub *op) {
    op->a.accept(this);
    op->b.accept(this);
}

void IRVisitor::visit(const Mul *op) {
    op->a.accept(this);
    op->b.accept(this);
}

void IRVisitor::visit(const Div *op) {
    op->a.accept(this);
    op->b.accept(this);
}

void IRVisitor::visit(const Mod *op) {
    op->a.accept(this);
    op->b.accept(this);
}

void IRVisitor::visit(const Min *op) {
    op->a.accept(this);
    op->b.accept(this);
}

void IRVisitor::visit(const Max *op) {
    op->a.accept(this);
    op->b.accept(this);
}

void IRVisitor::visit(const EQ *op) {
    op->a.accept(this);
    op->b.accept(this);
}

void IRVisitor::visit(const NE *op) {
    op->a.accept(this);
    op->b.accept(this);
}

void IRVisitor::visit(const LT *op) {
    op->a.accept(this);
    op->b.accept(this);
}

void IRVisitor::visit(const LE *op) {
    op->a.accept(this);
    op->b.accept(this);
}

void IRVisitor::visit(const GT *op) {
    op->a.accept(this);
    op->b.accept(this);
}

void IRVisitor::visit(const GE *op) {
    op->a.accept(this);
    op->b.accept(this);
}

void IRVisitor::visit(const And *op) {
    op->a.accept(this);
    op->b.accept(this);
}

void IRVisitor::visit(const Or *op) {
    op->a.accept(this);
    op->b.accept(this);
}

void IRVisitor::visit(const Not *op) {
    op->a.accept(this);
}

void IRVisitor::visit(const Select *op) {
    op->condition.accept(this);
    op->true_value.accept(this);
    op->false_value.accept(this);
}

void IRVisitor::visit(const Load *op) {
    op->index.accept(this);
}

void IRVisitor::visit(const Ramp *op) {
    op->base.accept(this);
    op->stride.accept(this);
}

void IRVisitor::visit(const Broadcast *op) {
    op->value.accept(this);
}

void IRVisitor::visit(const Call *op) {
    for (size_t i = 0; i < op->args.size(); i++) {
        op->args[i].accept(this);
    }

    // Consider extern call args
    Function f = op->func;
    if (op->call_type == Call::Halide && f.has_extern_definition()) {
        for (size_t i = 0; i < f.extern_arguments().size(); i++) {
            ExternFuncArgument arg = f.extern_arguments()[i];
            if (arg.is_expr()) {
                arg.expr.accept(this);
            }
        }
    }
}

void IRVisitor::visit(const Let *op) {
    op->value.accept(this);
    op->body.accept(this);
}

void IRVisitor::visit(const LetStmt *op) {
    op->value.accept(this);
    op->body.accept(this);
}

void IRVisitor::visit(const AssertStmt *op) {
    op->condition.accept(this);
}

void IRVisitor::visit(const Pipeline *op) {
    op->produce.accept(this);
    if (op->update.defined()) op->update.accept(this);
    op->consume.accept(this);
}

void IRVisitor::visit(const For *op) {
    op->min.accept(this);
    op->extent.accept(this);
    op->body.accept(this);
}

void IRVisitor::visit(const Store *op) {
    op->value.accept(this);
    op->index.accept(this);
}

void IRVisitor::visit(const Provide *op) {
    for (size_t i = 0; i < op->values.size(); i++) {
        op->values[i].accept(this);
    }
    for (size_t i = 0; i < op->args.size(); i++) {
        op->args[i].accept(this);
    }
}

void IRVisitor::visit(const Allocate *op) {
    for (size_t i = 0; i < op->extents.size(); i++) {
      op->extents[i].accept(this);
    }
    op->condition.accept(this);
    op->body.accept(this);
}

void IRVisitor::visit(const Free *op) {
}

void IRVisitor::visit(const Realize *op) {
    for (size_t i = 0; i < op->bounds.size(); i++) {
        op->bounds[i].min.accept(this);
        op->bounds[i].extent.accept(this);
    }
    op->condition.accept(this);
    op->body.accept(this);
}

void IRVisitor::visit(const Block *op) {
    op->first.accept(this);
    if (op->rest.defined()) {
        op->rest.accept(this);
    }
}

void IRVisitor::visit(const IfThenElse *op) {
    op->condition.accept(this);
    op->then_case.accept(this);
    if (op->else_case.defined()) {
        op->else_case.accept(this);
    }
}

void IRVisitor::visit(const Evaluate *op) {
    op->value.accept(this);
}

void IRGraphVisitor::include(const Expr &e) {
    if (visited.count(e.ptr)) {
        return;
    } else {
        visited.insert(e.ptr);
        e.accept(this);
        return;
    }
}

void IRGraphVisitor::include(const Stmt &s) {
    if (visited.count(s.ptr)) {
        return;
    } else {
        visited.insert(s.ptr);
        s.accept(this);
        return;
    }
}

void IRGraphVisitor::visit(const IntImm *) {
}

void IRGraphVisitor::visit(const FloatImm *) {
}

void IRGraphVisitor::visit(const StringImm *) {
}

void IRGraphVisitor::visit(const Cast *op) {
    include(op->value);
}

void IRGraphVisitor::visit(const Variable *op) {
}

void IRGraphVisitor::visit(const Add *op) {
    include(op->a);
    include(op->b);
}

void IRGraphVisitor::visit(const Sub *op) {
    include(op->a);
    include(op->b);
}

void IRGraphVisitor::visit(const Mul *op) {
    include(op->a);
    include(op->b);
}

void IRGraphVisitor::visit(const Div *op) {
    include(op->a);
    include(op->b);
}

void IRGraphVisitor::visit(const Mod *op) {
    include(op->a);
    include(op->b);
}

void IRGraphVisitor::visit(const Min *op) {
    include(op->a);
    include(op->b);
}

void IRGraphVisitor::visit(const Max *op) {
    include(op->a);
    include(op->b);
}

void IRGraphVisitor::visit(const EQ *op) {
    include(op->a);
    include(op->b);
}

void IRGraphVisitor::visit(const NE *op) {
    include(op->a);
    include(op->b);
}

void IRGraphVisitor::visit(const LT *op) {
    include(op->a);
    include(op->b);
}

void IRGraphVisitor::visit(const LE *op) {
    include(op->a);
    include(op->b);
}

void IRGraphVisitor::visit(const GT *op) {
    include(op->a);
    include(op->b);
}

void IRGraphVisitor::visit(const GE *op) {
    include(op->a);
    include(op->b);
}

void IRGraphVisitor::visit(const And *op) {
    include(op->a);
    include(op->b);
}

void IRGraphVisitor::visit(const Or *op) {
    include(op->a);
    include(op->b);
}

void IRGraphVisitor::visit(const Not *op) {
    include(op->a);
}

void IRGraphVisitor::visit(const Select *op) {
    include(op->condition);
    include(op->true_value);
    include(op->false_value);
}

void IRGraphVisitor::visit(const Load *op) {
    include(op->index);
}

void IRGraphVisitor::visit(const Ramp *op) {
    include(op->base);
    include(op->stride);
}

void IRGraphVisitor::visit(const Broadcast *op) {
    include(op->value);
}

void IRGraphVisitor::visit(const Call *op) {
    for (size_t i = 0; i < op->args.size(); i++) {
        include(op->args[i]);
    }
}

void IRGraphVisitor::visit(const Let *op) {
    include(op->value);
    include(op->body);
}

void IRGraphVisitor::visit(const LetStmt *op) {
    include(op->value);
    include(op->body);
}

void IRGraphVisitor::visit(const AssertStmt *op) {
    include(op->condition);
}

void IRGraphVisitor::visit(const Pipeline *op) {
    include(op->produce);
    if (op->update.defined()) include(op->update);
    include(op->consume);
}

void IRGraphVisitor::visit(const For *op) {
    include(op->min);
    include(op->extent);
    include(op->body);
}

void IRGraphVisitor::visit(const Store *op) {
    include(op->value);
    include(op->index);
}

void IRGraphVisitor::visit(const Provide *op) {
    for (size_t i = 0; i < op->values.size(); i++) {
        include(op->values[i]);
    }
    for (size_t i = 0; i < op->args.size(); i++) {
        include(op->args[i]);
    }
}

void IRGraphVisitor::visit(const Allocate *op) {
    for (size_t i = 0; i < op->extents.size(); i++) {
        include(op->extents[i]);
    }
    include(op->condition);
    include(op->body);
}

void IRGraphVisitor::visit(const Free *op) {
}

void IRGraphVisitor::visit(const Realize *op) {
    for (size_t i = 0; i < op->bounds.size(); i++) {
        include(op->bounds[i].min);
        include(op->bounds[i].extent);
    }
    include(op->condition);
    include(op->body);
}

void IRGraphVisitor::visit(const Block *op) {
    include(op->first);
    if (op->rest.defined()) include(op->rest);
}

void IRGraphVisitor::visit(const IfThenElse *op) {
    include(op->condition);
    include(op->then_case);
    if (op->else_case.defined()) {
        include(op->else_case);
    }
}

void IRGraphVisitor::visit(const Evaluate *op) {
    include(op->value);
}

}
}
<commit_msg>IRVisitor wasn't visiting the message in an assert<commit_after>#include "IRVisitor.h"
#include "IR.h"

namespace Halide {
namespace Internal {

IRVisitor::~IRVisitor() {
}

void IRVisitor::visit(const IntImm *) {
}

void IRVisitor::visit(const FloatImm *) {
}

void IRVisitor::visit(const StringImm *) {
}

void IRVisitor::visit(const Cast *op) {
    op->value.accept(this);
}

void IRVisitor::visit(const Variable *) {
}

void IRVisitor::visit(const Add *op) {
    op->a.accept(this);
    op->b.accept(this);
}

void IRVisitor::visit(const Sub *op) {
    op->a.accept(this);
    op->b.accept(this);
}

void IRVisitor::visit(const Mul *op) {
    op->a.accept(this);
    op->b.accept(this);
}

void IRVisitor::visit(const Div *op) {
    op->a.accept(this);
    op->b.accept(this);
}

void IRVisitor::visit(const Mod *op) {
    op->a.accept(this);
    op->b.accept(this);
}

void IRVisitor::visit(const Min *op) {
    op->a.accept(this);
    op->b.accept(this);
}

void IRVisitor::visit(const Max *op) {
    op->a.accept(this);
    op->b.accept(this);
}

void IRVisitor::visit(const EQ *op) {
    op->a.accept(this);
    op->b.accept(this);
}

void IRVisitor::visit(const NE *op) {
    op->a.accept(this);
    op->b.accept(this);
}

void IRVisitor::visit(const LT *op) {
    op->a.accept(this);
    op->b.accept(this);
}

void IRVisitor::visit(const LE *op) {
    op->a.accept(this);
    op->b.accept(this);
}

void IRVisitor::visit(const GT *op) {
    op->a.accept(this);
    op->b.accept(this);
}

void IRVisitor::visit(const GE *op) {
    op->a.accept(this);
    op->b.accept(this);
}

void IRVisitor::visit(const And *op) {
    op->a.accept(this);
    op->b.accept(this);
}

void IRVisitor::visit(const Or *op) {
    op->a.accept(this);
    op->b.accept(this);
}

void IRVisitor::visit(const Not *op) {
    op->a.accept(this);
}

void IRVisitor::visit(const Select *op) {
    op->condition.accept(this);
    op->true_value.accept(this);
    op->false_value.accept(this);
}

void IRVisitor::visit(const Load *op) {
    op->index.accept(this);
}

void IRVisitor::visit(const Ramp *op) {
    op->base.accept(this);
    op->stride.accept(this);
}

void IRVisitor::visit(const Broadcast *op) {
    op->value.accept(this);
}

void IRVisitor::visit(const Call *op) {
    for (size_t i = 0; i < op->args.size(); i++) {
        op->args[i].accept(this);
    }

    // Consider extern call args
    Function f = op->func;
    if (op->call_type == Call::Halide && f.has_extern_definition()) {
        for (size_t i = 0; i < f.extern_arguments().size(); i++) {
            ExternFuncArgument arg = f.extern_arguments()[i];
            if (arg.is_expr()) {
                arg.expr.accept(this);
            }
        }
    }
}

void IRVisitor::visit(const Let *op) {
    op->value.accept(this);
    op->body.accept(this);
}

void IRVisitor::visit(const LetStmt *op) {
    op->value.accept(this);
    op->body.accept(this);
}

void IRVisitor::visit(const AssertStmt *op) {
    op->condition.accept(this);
    op->message.accept(this)
}

void IRVisitor::visit(const Pipeline *op) {
    op->produce.accept(this);
    if (op->update.defined()) op->update.accept(this);
    op->consume.accept(this);
}

void IRVisitor::visit(const For *op) {
    op->min.accept(this);
    op->extent.accept(this);
    op->body.accept(this);
}

void IRVisitor::visit(const Store *op) {
    op->value.accept(this);
    op->index.accept(this);
}

void IRVisitor::visit(const Provide *op) {
    for (size_t i = 0; i < op->values.size(); i++) {
        op->values[i].accept(this);
    }
    for (size_t i = 0; i < op->args.size(); i++) {
        op->args[i].accept(this);
    }
}

void IRVisitor::visit(const Allocate *op) {
    for (size_t i = 0; i < op->extents.size(); i++) {
      op->extents[i].accept(this);
    }
    op->condition.accept(this);
    op->body.accept(this);
}

void IRVisitor::visit(const Free *op) {
}

void IRVisitor::visit(const Realize *op) {
    for (size_t i = 0; i < op->bounds.size(); i++) {
        op->bounds[i].min.accept(this);
        op->bounds[i].extent.accept(this);
    }
    op->condition.accept(this);
    op->body.accept(this);
}

void IRVisitor::visit(const Block *op) {
    op->first.accept(this);
    if (op->rest.defined()) {
        op->rest.accept(this);
    }
}

void IRVisitor::visit(const IfThenElse *op) {
    op->condition.accept(this);
    op->then_case.accept(this);
    if (op->else_case.defined()) {
        op->else_case.accept(this);
    }
}

void IRVisitor::visit(const Evaluate *op) {
    op->value.accept(this);
}

void IRGraphVisitor::include(const Expr &e) {
    if (visited.count(e.ptr)) {
        return;
    } else {
        visited.insert(e.ptr);
        e.accept(this);
        return;
    }
}

void IRGraphVisitor::include(const Stmt &s) {
    if (visited.count(s.ptr)) {
        return;
    } else {
        visited.insert(s.ptr);
        s.accept(this);
        return;
    }
}

void IRGraphVisitor::visit(const IntImm *) {
}

void IRGraphVisitor::visit(const FloatImm *) {
}

void IRGraphVisitor::visit(const StringImm *) {
}

void IRGraphVisitor::visit(const Cast *op) {
    include(op->value);
}

void IRGraphVisitor::visit(const Variable *op) {
}

void IRGraphVisitor::visit(const Add *op) {
    include(op->a);
    include(op->b);
}

void IRGraphVisitor::visit(const Sub *op) {
    include(op->a);
    include(op->b);
}

void IRGraphVisitor::visit(const Mul *op) {
    include(op->a);
    include(op->b);
}

void IRGraphVisitor::visit(const Div *op) {
    include(op->a);
    include(op->b);
}

void IRGraphVisitor::visit(const Mod *op) {
    include(op->a);
    include(op->b);
}

void IRGraphVisitor::visit(const Min *op) {
    include(op->a);
    include(op->b);
}

void IRGraphVisitor::visit(const Max *op) {
    include(op->a);
    include(op->b);
}

void IRGraphVisitor::visit(const EQ *op) {
    include(op->a);
    include(op->b);
}

void IRGraphVisitor::visit(const NE *op) {
    include(op->a);
    include(op->b);
}

void IRGraphVisitor::visit(const LT *op) {
    include(op->a);
    include(op->b);
}

void IRGraphVisitor::visit(const LE *op) {
    include(op->a);
    include(op->b);
}

void IRGraphVisitor::visit(const GT *op) {
    include(op->a);
    include(op->b);
}

void IRGraphVisitor::visit(const GE *op) {
    include(op->a);
    include(op->b);
}

void IRGraphVisitor::visit(const And *op) {
    include(op->a);
    include(op->b);
}

void IRGraphVisitor::visit(const Or *op) {
    include(op->a);
    include(op->b);
}

void IRGraphVisitor::visit(const Not *op) {
    include(op->a);
}

void IRGraphVisitor::visit(const Select *op) {
    include(op->condition);
    include(op->true_value);
    include(op->false_value);
}

void IRGraphVisitor::visit(const Load *op) {
    include(op->index);
}

void IRGraphVisitor::visit(const Ramp *op) {
    include(op->base);
    include(op->stride);
}

void IRGraphVisitor::visit(const Broadcast *op) {
    include(op->value);
}

void IRGraphVisitor::visit(const Call *op) {
    for (size_t i = 0; i < op->args.size(); i++) {
        include(op->args[i]);
    }
}

void IRGraphVisitor::visit(const Let *op) {
    include(op->value);
    include(op->body);
}

void IRGraphVisitor::visit(const LetStmt *op) {
    include(op->value);
    include(op->body);
}

void IRGraphVisitor::visit(const AssertStmt *op) {
    include(op->condition);
    include(op->message);
}

void IRGraphVisitor::visit(const Pipeline *op) {
    include(op->produce);
    if (op->update.defined()) include(op->update);
    include(op->consume);
}

void IRGraphVisitor::visit(const For *op) {
    include(op->min);
    include(op->extent);
    include(op->body);
}

void IRGraphVisitor::visit(const Store *op) {
    include(op->value);
    include(op->index);
}

void IRGraphVisitor::visit(const Provide *op) {
    for (size_t i = 0; i < op->values.size(); i++) {
        include(op->values[i]);
    }
    for (size_t i = 0; i < op->args.size(); i++) {
        include(op->args[i]);
    }
}

void IRGraphVisitor::visit(const Allocate *op) {
    for (size_t i = 0; i < op->extents.size(); i++) {
        include(op->extents[i]);
    }
    include(op->condition);
    include(op->body);
}

void IRGraphVisitor::visit(const Free *op) {
}

void IRGraphVisitor::visit(const Realize *op) {
    for (size_t i = 0; i < op->bounds.size(); i++) {
        include(op->bounds[i].min);
        include(op->bounds[i].extent);
    }
    include(op->condition);
    include(op->body);
}

void IRGraphVisitor::visit(const Block *op) {
    include(op->first);
    if (op->rest.defined()) include(op->rest);
}

void IRGraphVisitor::visit(const IfThenElse *op) {
    include(op->condition);
    include(op->then_case);
    if (op->else_case.defined()) {
        include(op->else_case);
    }
}

void IRGraphVisitor::visit(const Evaluate *op) {
    include(op->value);
}

}
}
<|endoftext|>


<commit_before>#include "domain.h"
#include "person.h"
#include <iostream>
#include <algorithm>
#include <vector>
#include "data.h"
#include "console.h"

using namespace std;

Domain::Domain()
{

}

bool agePerson (const Person& lsh, const Person& rhs) // sort by birthyear
{
    return (lsh.getBirth() < rhs.getBirth());
}

void Domain::ageSorting(vector<Person>& ageSort) //sort by birthyear
{
    std::sort(ageSort.begin(), ageSort.end(), agePerson);
}

bool nameAlpha(const Person& lhs, const Person& rhs)
{
    return (lhs.getName() < rhs.getName());
}

void Domain::alphabeticSort(vector<Person>& alphaSort)
{
    std::sort(alphaSort.begin(), alphaSort.end(), nameAlpha);
}

int Domain::findAge(Person& sciAge) const
{
    int x;
    int y;
    int resultDead;
    int resultAlive;
    const int currentYear = 2016;
    x = sciAge.getDeath();
    y = sciAge.getBirth();

    if(x == 0)
    {
        resultAlive = currentYear - y;
        return resultAlive;
    }
    else
    {
        resultDead = x - y;
        return resultDead;
    }
}

vector<Person> Domain::search(vector<Person>& p, string name)
{
    vector<Person> results;
//Search function, we search from out vector and then put the results in another vector so it shows us all results
    for(unsigned int i = 0; i < p.size(); i++)
    {
        string nameFind;
        char genderFind;
        int birthFind;
        int deathFind;
        nameFind = p[i].getName();
        std::size_t found = nameFind.find(name);

        if (found!=std::string::npos)
        {
            p[i].getName();
            genderFind = p[i].getGender();
            birthFind = p[i].getBirth();
            deathFind = p[i].getDeath();
            Person p2(nameFind, genderFind, birthFind, deathFind);
            results.push_back(p2);
        }
    }
    return results;
}
<commit_msg>testa email<commit_after>#include "domain.h"
#include "person.h"
#include <iostream>
#include <algorithm>
#include <vector>
#include "data.h"
#include "console.h"

using namespace std;

Domain::Domain()
{
asdf
}

bool agePerson (const Person& lsh, const Person& rhs) // sort by birthyear
{
    return (lsh.getBirth() < rhs.getBirth());
}

void Domain::ageSorting(vector<Person>& ageSort) //sort by birthyear
{
    std::sort(ageSort.begin(), ageSort.end(), agePerson);
}

bool nameAlpha(const Person& lhs, const Person& rhs)
{
    return (lhs.getName() < rhs.getName());
}

void Domain::alphabeticSort(vector<Person>& alphaSort)
{
    std::sort(alphaSort.begin(), alphaSort.end(), nameAlpha);
}

int Domain::findAge(Person& sciAge) const
{
    int x;
    int y;
    int resultDead;
    int resultAlive;
    const int currentYear = 2016;
    x = sciAge.getDeath();
    y = sciAge.getBirth();

    if(x == 0)
    {
        resultAlive = currentYear - y;
        return resultAlive;
    }
    else
    {
        resultDead = x - y;
        return resultDead;
    }
}

vector<Person> Domain::search(vector<Person>& p, string name)
{
    vector<Person> results;
//Search function, we search from out vector and then put the results in another vector so it shows us all results
    for(unsigned int i = 0; i < p.size(); i++)
    {
        string nameFind;
        char genderFind;
        int birthFind;
        int deathFind;
        nameFind = p[i].getName();
        std::size_t found = nameFind.find(name);

        if (found!=std::string::npos)
        {
            p[i].getName();
            genderFind = p[i].getGender();
            birthFind = p[i].getBirth();
            deathFind = p[i].getDeath();
            Person p2(nameFind, genderFind, birthFind, deathFind);
            results.push_back(p2);
        }
    }
    return results;
}
<|endoftext|>


<commit_before><commit_msg>& next to type name<commit_after><|endoftext|>


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

#include "paddle/framework/eigen.h"
#include <gtest/gtest.h>

namespace paddle {
namespace framework {

TEST(EigenDim, From) {
  EigenDim<3>::Type ed = EigenDim<3>::From(make_ddim({1, 2, 3}));
  EXPECT_EQ(1, ed[0]);
  EXPECT_EQ(2, ed[1]);
  EXPECT_EQ(3, ed[2]);
}

TEST(Eigen, Tensor) {
  Tensor t;
  float* p = t.mutable_data<float>(make_ddim({1, 2, 3}), platform::CPUPlace());
  for (int i = 0; i < 1 * 2 * 3; i++) {
    p[i] = static_cast<float>(i);
  }

  EigenTensor<float, 3>::Type et = EigenTensor<float, 3>::From(t);

  EXPECT_EQ(1, et.dimension(0));
  EXPECT_EQ(2, et.dimension(1));
  EXPECT_EQ(3, et.dimension(2));

  for (int i = 0; i < 1; i++) {
    for (int j = 0; j < 2; j++) {
      for (int k = 0; k < 3; k++) {
        EXPECT_EQ((i * 2 + j) * 3 + k, et(i, j, k));
      }
    }
  }
  for (int i = 0; i < 1 * 2 * 3; i++) {
    EXPECT_EQ(i, et(i));
  }
}

TEST(Eigen, VectorFrom) {
  Tensor t;
  float* p = t.mutable_data<float>(make_ddim({6}), platform::CPUPlace());
  for (int i = 0; i < 6; i++) {
    p[i] = static_cast<float>(i);
  }

  EigenVector<float>::Type ev = EigenVector<float>::From(t);

  EXPECT_EQ(6, ev.dimension(0));

  for (int i = 0; i < 6; i++) {
    EXPECT_EQ(i, ev(i));
  }
}

TEST(Eigen, VectorFlatten) {
  Tensor t;
  float* p = t.mutable_data<float>(make_ddim({1, 2, 3}), platform::CPUPlace());
  for (int i = 0; i < 1 * 2 * 3; i++) {
    p[i] = static_cast<float>(i);
  }

  EigenVector<float>::Type ev = EigenVector<float>::Flatten(t);

  EXPECT_EQ(1 * 2 * 3, ev.dimension(0));

  for (int i = 0; i < 1 * 2 * 3; i++) {
    EXPECT_EQ(i, ev(i));
  }
}

TEST(Eigen, Matrix) {
  Tensor t;
  float* p = t.mutable_data<float>(make_ddim({2, 3}), platform::CPUPlace());
  for (int i = 0; i < 2 * 3; i++) {
    p[i] = static_cast<float>(i);
  }

  EigenMatrix<float>::Type em = EigenMatrix<float>::From(t);

  EXPECT_EQ(2, em.dimension(0));
  EXPECT_EQ(3, em.dimension(1));

  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 3; j++) {
      EXPECT_EQ(i * 3 + j, em(i, j));
    }
  }
}

}  // namespace framework
}  // namespace paddle
<commit_msg>change EQ to NEAR for float value<commit_after>/*
  Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at
  http://www.apache.org/licenses/LICENSE-2.0
  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/

#include "paddle/framework/eigen.h"
#include <gtest/gtest.h>

namespace paddle {
namespace framework {

TEST(EigenDim, From) {
  EigenDim<3>::Type ed = EigenDim<3>::From(make_ddim({1, 2, 3}));
  ASSERT_EQ(1, ed[0]);
  ASSERT_EQ(2, ed[1]);
  ASSERT_EQ(3, ed[2]);
}

TEST(Eigen, Tensor) {
  Tensor t;
  float* p = t.mutable_data<float>(make_ddim({1, 2, 3}), platform::CPUPlace());
  for (int i = 0; i < 1 * 2 * 3; i++) {
    p[i] = static_cast<float>(i);
  }

  EigenTensor<float, 3>::Type et = EigenTensor<float, 3>::From(t);

  ASSERT_EQ(1, et.dimension(0));
  ASSERT_EQ(2, et.dimension(1));
  ASSERT_EQ(3, et.dimension(2));

  for (int i = 0; i < 1; i++) {
    for (int j = 0; j < 2; j++) {
      for (int k = 0; k < 3; k++) {
        ASSERT_NEAR((i * 2 + j) * 3 + k, et(i, j, k), 1e-6f);
      }
    }
  }
}

TEST(Eigen, VectorFrom) {
  Tensor t;
  float* p = t.mutable_data<float>(make_ddim({6}), platform::CPUPlace());
  for (int i = 0; i < 6; i++) {
    p[i] = static_cast<float>(i);
  }

  EigenVector<float>::Type ev = EigenVector<float>::From(t);

  ASSERT_EQ(6, ev.dimension(0));

  for (int i = 0; i < 6; i++) {
    ASSERT_NEAR(i, ev(i), 1e-6f);
  }
}

TEST(Eigen, VectorFlatten) {
  Tensor t;
  float* p = t.mutable_data<float>(make_ddim({1, 2, 3}), platform::CPUPlace());
  for (int i = 0; i < 1 * 2 * 3; i++) {
    p[i] = static_cast<float>(i);
  }

  EigenVector<float>::Type ev = EigenVector<float>::Flatten(t);

  ASSERT_EQ(1 * 2 * 3, ev.dimension(0));

  for (int i = 0; i < 1 * 2 * 3; i++) {
    ASSERT_NEAR(i, ev(i), 1e-6f);
  }
}

TEST(Eigen, Matrix) {
  Tensor t;
  float* p = t.mutable_data<float>(make_ddim({2, 3}), platform::CPUPlace());
  for (int i = 0; i < 2 * 3; i++) {
    p[i] = static_cast<float>(i);
  }

  EigenMatrix<float>::Type em = EigenMatrix<float>::From(t);

  ASSERT_EQ(2, em.dimension(0));
  ASSERT_EQ(3, em.dimension(1));

  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 3; j++) {
      ASSERT_NEAR(i * 3 + j, em(i, j), 1e-6f);
    }
  }
}

}  // namespace framework
}  // namespace paddle
<|endoftext|>


<commit_before>#include "States.h"

enum DemoPages
{
	PAGE_SPRITE,
	PAGE_TILED,
	PAGE_TEXT,
	PAGE_TEXTPATH,
	PAGE_CONTROLLER,
	PAGE_ASCII,
	PAGE_TILEMAP,
	PAGE_COLLISION,
	PAGE_INTERPOLATE,
	PAGE_PARTICLES,
	PAGE_TRAILAREA,
	PAGE_BACKDROP,
	PAGE_LIGHTING2D,
	PAGE_GRAPHICS3D,
	PAGE_ASYNC,
	NUM_DEMOPAGES,
};

void DemoStatesManager::SetNewPage()
{
	if (VGlobal::p()->PostProcess)
	{
		delete VGlobal::p()->PostProcess;
		VGlobal::p()->PostProcess = NULL;
	}

	VSubState* subState;
	switch (CurrentPage)
	{
		case PAGE_ASCII:
			subState = new ASCIITestState();
			break;
		case PAGE_ASYNC:
			subState = new AsyncTestState();
			break;
		case PAGE_BACKDROP:
			subState = new BackdropState();
			break;
		case PAGE_COLLISION:
			subState = new CollisionState();
			break;
		case PAGE_CONTROLLER:
			subState = new ControllerState();
			break;
		case PAGE_GRAPHICS3D:
			subState = new Graphics3DState();
			break;
		case PAGE_INTERPOLATE:
			subState = new InterpolateState();
			break;
		case PAGE_LIGHTING2D:
			subState = new Lighting2DState();
			break;
		case PAGE_PARTICLES:
			subState = new ParticlesState();
			break;
		case PAGE_SPRITE:
			subState = new SpriteState();
			break;
		case PAGE_TEXT:
			subState = new TextState();
			break;
		case PAGE_TEXTPATH:
			subState = new WordShapeState();
			break;
		case PAGE_TILED:
			subState = new TiledState();
			break;
		case PAGE_TILEMAP:
			subState = new TilemapState();
			break;
		case PAGE_TRAILAREA:
			subState = new TrailAreaState();
			break;
		default:
			subState = NULL;
			break;
	}

	auto stateText = new VGroup(3);
	auto title = new VText(sf::Vector2f(0.0f, 2.0f), (float)VGlobal::p()->Width, "SFML VFrame", 24);
	title->Alignment = VTextAlign::ALIGNCENTRE;
	title->ScrollFactor = sf::Vector2f();
	title->ZoomFactor = 0;

	std::stringstream ss;
	ss << "Version: " << VFRAME_VERSION;
	auto version = new VText(5.0f, 10.0f, (float)VGlobal::p()->Width - 10.0f, ss.str(), 12);
	version->Alignment = VTextAlign::ALIGNRIGHT;
	version->ScrollFactor = sf::Vector2f();
	version->ZoomFactor = 0;

	auto header = new VSprite();
	header->MakeGraphic(VGlobal::p()->Width, (int)(title->Position.y + 32), sf::Color::Black);
	header->ScrollFactor = sf::Vector2f();
	header->ZoomFactor = 0;

	Cameras[0]->Reset();
	VGlobal::p()->BackgroundColor = sf::Color::Black;

	if (VTimeManager::AnyActiveTimers())
	{
		VTimeManager::p()->Clear();
	}

	OpenSubState(subState);
	ResetSubState();

	stateText->Add(header);
	stateText->Add(title);
	stateText->Add(version);
	//subState->Add(stateText);
}

void DemoStatesManager::Initialise()
{
	VSUPERCLASS::Initialise();
	SetNewPage();

#ifdef USE_GAMEPAD_API
	VGlobal::p()->Input.SetAxisInput("leftX", sf::Keyboard::D, sf::Keyboard::A, VInputHandler::XAxis::PovX);
	VGlobal::p()->Input.SetAxisInput("leftY", sf::Keyboard::S, sf::Keyboard::W, VInputHandler::XAxis::PovY);
	VGlobal::p()->Input.SetAxisInput("rightX", sf::Keyboard::L, sf::Keyboard::J, VInputHandler::XAxis::Z);
	VGlobal::p()->Input.SetAxisInput("rightY", sf::Keyboard::K, sf::Keyboard::I, VInputHandler::XAxis::V);
	VGlobal::p()->Input.SetAxisInput("LT", sf::Keyboard::E, sf::Keyboard::Q, VInputHandler::XAxis::L);
	VGlobal::p()->Input.SetAxisInput("RT", sf::Keyboard::O, sf::Keyboard::U, VInputHandler::XAxis::R);
	VGlobal::p()->Input.SetButtonInput("A", sf::Keyboard::N, BUTTON_A);
	VGlobal::p()->Input.SetButtonInput("B", sf::Keyboard::M, BUTTON_B);
	VGlobal::p()->Input.SetButtonInput("X", sf::Keyboard::H, BUTTON_X);
	VGlobal::p()->Input.SetButtonInput("Y", sf::Keyboard::J, BUTTON_Y);
	VGlobal::p()->Input.SetButtonInput("leftShoulder", sf::Keyboard::T, BUTTON_LEFT_SHOULDER);
	VGlobal::p()->Input.SetButtonInput("rightShoulder", sf::Keyboard::Y, BUTTON_RIGHT_SHOULDER);
	VGlobal::p()->Input.SetButtonInput("leftStick", sf::Keyboard::B, BUTTON_LEFT_THUMB);
	VGlobal::p()->Input.SetButtonInput("rightStick", sf::Keyboard::N, BUTTON_RIGHT_THUMB);
	VGlobal::p()->Input.SetButtonInput("Back", sf::Keyboard::BackSpace, BUTTON_BACK);
	VGlobal::p()->Input.SetButtonInput("Start", sf::Keyboard::Return, BUTTON_START);
#elif defined(USE_SFML_JOYSTICK)
	VGlobal::p()->Input.SetAxisInput("leftX", sf::Keyboard::D, sf::Keyboard::A, sf::Joystick::Axis::X);
	VGlobal::p()->Input.SetAxisInput("leftY", sf::Keyboard::S, sf::Keyboard::W, sf::Joystick::Axis::Y);
	VGlobal::p()->Input.SetAxisInput("rightX", sf::Keyboard::L, sf::Keyboard::J, sf::Joystick::Axis::U);
	VGlobal::p()->Input.SetAxisInput("rightY", sf::Keyboard::K, sf::Keyboard::I, sf::Joystick::Axis::R);
	VGlobal::p()->Input.SetAxisInput("LT", sf::Keyboard::E, sf::Keyboard::Q, sf::Joystick::Axis::Z);
	VGlobal::p()->Input.SetAxisInput("RT", sf::Keyboard::O, sf::Keyboard::U, sf::Joystick::Axis::Z);
	VGlobal::p()->Input.SetButtonInput("A", sf::Keyboard::N, VInputHandler::BUTTON_A);
	VGlobal::p()->Input.SetButtonInput("B", sf::Keyboard::M, VInputHandler::BUTTON_B);
	VGlobal::p()->Input.SetButtonInput("X", sf::Keyboard::H, VInputHandler::BUTTON_X);
	VGlobal::p()->Input.SetButtonInput("Y", sf::Keyboard::J, VInputHandler::BUTTON_Y);
	VGlobal::p()->Input.SetButtonInput("leftShoulder", sf::Keyboard::T, VInputHandler::BUTTON_LEFT_SHOULDER);
	VGlobal::p()->Input.SetButtonInput("rightShoulder", sf::Keyboard::Y, VInputHandler::BUTTON_RIGHT_SHOULDER);
	VGlobal::p()->Input.SetButtonInput("leftStick", sf::Keyboard::B, VInputHandler::BUTTON_LEFT_THUMB);
	VGlobal::p()->Input.SetButtonInput("rightStick", sf::Keyboard::N, VInputHandler::BUTTON_RIGHT_THUMB);
	VGlobal::p()->Input.SetButtonInput("Back", sf::Keyboard::BackSpace, VInputHandler::BUTTON_BACK);
	VGlobal::p()->Input.SetButtonInput("Start", sf::Keyboard::Return, VInputHandler::BUTTON_START);
	VGlobal::p()->Input.SetButtonInput("Home", sf::Keyboard::Home, VInputHandler::BUTTON_HOME);
#else
	VGlobal::p()->Input.SetAxisInput("leftX", sf::Keyboard::D, sf::Keyboard::A, sf::XInputDevice::XAxis::PovX);
	VGlobal::p()->Input.SetAxisInput("leftY", sf::Keyboard::S, sf::Keyboard::W, sf::XInputDevice::XAxis::PovY);
	VGlobal::p()->Input.SetAxisInput("rightX", sf::Keyboard::L, sf::Keyboard::J, sf::XInputDevice::XAxis::Z);
	VGlobal::p()->Input.SetAxisInput("rightY", sf::Keyboard::K, sf::Keyboard::I, sf::XInputDevice::XAxis::V);
	VGlobal::p()->Input.SetAxisInput("LT", sf::Keyboard::E, sf::Keyboard::Q, sf::XInputDevice::XAxis::L);
	VGlobal::p()->Input.SetAxisInput("RT", sf::Keyboard::O, sf::Keyboard::U, sf::XInputDevice::XAxis::R);
	VGlobal::p()->Input.SetButtonInput("A", sf::Keyboard::N, sf::XInputDevice::A);
	VGlobal::p()->Input.SetButtonInput("B", sf::Keyboard::M, sf::XInputDevice::B);
	VGlobal::p()->Input.SetButtonInput("X", sf::Keyboard::H, sf::XInputDevice::X);
	VGlobal::p()->Input.SetButtonInput("Y", sf::Keyboard::J, sf::XInputDevice::Y);
	VGlobal::p()->Input.SetButtonInput("leftShoulder", sf::Keyboard::T, sf::XInputDevice::LB);
	VGlobal::p()->Input.SetButtonInput("rightShoulder", sf::Keyboard::Y, sf::XInputDevice::RB);
	VGlobal::p()->Input.SetButtonInput("leftStick", sf::Keyboard::B, sf::XInputDevice::LEFT_THUMB);
	VGlobal::p()->Input.SetButtonInput("rightStick", sf::Keyboard::N, sf::XInputDevice::RIGHT_THUMB);
	VGlobal::p()->Input.SetButtonInput("Back", sf::Keyboard::BackSpace, sf::XInputDevice::BACK);
	VGlobal::p()->Input.SetButtonInput("Start", sf::Keyboard::Return, sf::XInputDevice::START);
#endif
}

void DemoStatesManager::HandleEvents(const sf::Event& event)
{
	VSUPERCLASS::HandleEvents(event);

	if (event.type == sf::Event::KeyPressed)
	{
		if (event.key.code == sf::Keyboard::Left)
		{
			CurrentPage--;

			if (CurrentPage < 0)
				CurrentPage = NUM_DEMOPAGES - 1;

			SetNewPage();
		}

		if (event.key.code == sf::Keyboard::Right)
		{
			CurrentPage++;
			CurrentPage %= NUM_DEMOPAGES;

			SetNewPage();
		}

		if (event.key.code == sf::Keyboard::Q)
		{
			VGlobal::p()->DrawDebug = !VGlobal::p()->DrawDebug;
		}

		if (event.key.code == sf::Keyboard::E)
		{
			VGlobal::p()->Antialiasing = !VGlobal::p()->Antialiasing;
		}

		if (event.key.code == sf::Keyboard::F)
		{
			VGlobal::p()->ToggleFullscreen();
		}
	}
}
<commit_msg>Update to example to reflect VFrame updates<commit_after>#include "States.h"

enum DemoPages
{
	PAGE_SPRITE,
	PAGE_TILED,
	PAGE_TEXT,
	PAGE_TEXTPATH,
	PAGE_CONTROLLER,
	PAGE_ASCII,
	PAGE_TILEMAP,
	PAGE_COLLISION,
	PAGE_INTERPOLATE,
	PAGE_PARTICLES,
	PAGE_TRAILAREA,
	PAGE_BACKDROP,
	PAGE_LIGHTING2D,
	PAGE_GRAPHICS3D,
	PAGE_ASYNC,
	NUM_DEMOPAGES,
};

void DemoStatesManager::SetNewPage()
{
	VGlobal::p()->PostProcess.reset();

	VSubState* subState;
	switch (CurrentPage)
	{
		case PAGE_ASCII:
			subState = new ASCIITestState();
			break;
		case PAGE_ASYNC:
			subState = new AsyncTestState();
			break;
		case PAGE_BACKDROP:
			subState = new BackdropState();
			break;
		case PAGE_COLLISION:
			subState = new CollisionState();
			break;
		case PAGE_CONTROLLER:
			subState = new ControllerState();
			break;
		case PAGE_GRAPHICS3D:
			subState = new Graphics3DState();
			break;
		case PAGE_INTERPOLATE:
			subState = new InterpolateState();
			break;
		case PAGE_LIGHTING2D:
			subState = new Lighting2DState();
			break;
		case PAGE_PARTICLES:
			subState = new ParticlesState();
			break;
		case PAGE_SPRITE:
			subState = new SpriteState();
			break;
		case PAGE_TEXT:
			subState = new TextState();
			break;
		case PAGE_TEXTPATH:
			subState = new WordShapeState();
			break;
		case PAGE_TILED:
			subState = new TiledState();
			break;
		case PAGE_TILEMAP:
			subState = new TilemapState();
			break;
		case PAGE_TRAILAREA:
			subState = new TrailAreaState();
			break;
		default:
			subState = NULL;
			break;
	}

	if (SubState != nullptr)
	{
		if (SubState->GetIndexOfItem(stateText) >= 0)
		{
			SubState->Remove(stateText);
		}
	}

	OpenSubState(subState);

	Cameras[0]->Reset();
	VGlobal::p()->BackgroundColor = sf::Color::Black;

	if (VTimeManager::AnyActiveTimers())
	{
		VTimeManager::p()->Clear();
	}

	debugTimer = new VTimer(false);
	VTimeManager::p()->AddTimer(debugTimer);

	ResetSubState();
	subState->Add(stateText);
}

void DemoStatesManager::Initialise()
{
	VSUPERCLASS::Initialise();
	SetNewPage();

	auto title = new VText(sf::Vector2f(0.0f, 2.0f), (float)VGlobal::p()->Width, "SFML VFrame", 24);
	title->Alignment = VTextAlign::ALIGNCENTRE;
	title->ScrollFactor = sf::Vector2f();
	title->ZoomFactor = 0;
	title->ApplyChanges();

	std::stringstream ss;
	ss << "Version: " << VFRAME_VERSION;
	auto version = new VText(5.0f, 10.0f, (float)VGlobal::p()->Width - 10.0f, ss.str(), 12);
	version->Alignment = VTextAlign::ALIGNRIGHT;
	version->ScrollFactor = sf::Vector2f();
	version->ZoomFactor = 0;
	version->ApplyChanges();

	auto header = new VSprite();
	header->MakeGraphic(VGlobal::p()->Width, (int)(title->Position.y + 32), sf::Color::Black);
	header->ScrollFactor = sf::Vector2f();
	header->ZoomFactor = 0;

	auto debug = new VText(5.0f, 10.0f, (float)VGlobal::p()->Width - 10.0f, "", 12);
	debug->Alignment = VTextAlign::ALIGNLEFT;
	debug->ScrollFactor = sf::Vector2f();
	debug->ZoomFactor = 0;
	debug->ApplyChanges();
	debugMessages = debug;

	stateText = new VGroup(4);
	stateText->Add(header);
	stateText->Add(title);
	stateText->Add(version);
	stateText->Add(debugMessages);
	SubState->Add(stateText);

#ifdef USE_GAMEPAD_API
	VGlobal::p()->Input->SetAxisInput("leftX", sf::Keyboard::D, sf::Keyboard::A, VInputHandler::XAxis::PovX);
	VGlobal::p()->Input->SetAxisInput("leftY", sf::Keyboard::S, sf::Keyboard::W, VInputHandler::XAxis::PovY);
	VGlobal::p()->Input->SetAxisInput("rightX", sf::Keyboard::L, sf::Keyboard::J, VInputHandler::XAxis::Z);
	VGlobal::p()->Input->SetAxisInput("rightY", sf::Keyboard::K, sf::Keyboard::I, VInputHandler::XAxis::V);
	VGlobal::p()->Input->SetAxisInput("LT", sf::Keyboard::E, sf::Keyboard::Q, VInputHandler::XAxis::L);
	VGlobal::p()->Input->SetAxisInput("RT", sf::Keyboard::O, sf::Keyboard::U, VInputHandler::XAxis::R);
	VGlobal::p()->Input->SetButtonInput("A", sf::Keyboard::N, BUTTON_A);
	VGlobal::p()->Input->SetButtonInput("B", sf::Keyboard::M, BUTTON_B);
	VGlobal::p()->Input->SetButtonInput("X", sf::Keyboard::H, BUTTON_X);
	VGlobal::p()->Input->SetButtonInput("Y", sf::Keyboard::J, BUTTON_Y);
	VGlobal::p()->Input->SetButtonInput("leftShoulder", sf::Keyboard::T, BUTTON_LEFT_SHOULDER);
	VGlobal::p()->Input->SetButtonInput("rightShoulder", sf::Keyboard::Y, BUTTON_RIGHT_SHOULDER);
	VGlobal::p()->Input->SetButtonInput("leftStick", sf::Keyboard::B, BUTTON_LEFT_THUMB);
	VGlobal::p()->Input->SetButtonInput("rightStick", sf::Keyboard::N, BUTTON_RIGHT_THUMB);
	VGlobal::p()->Input->SetButtonInput("Back", sf::Keyboard::BackSpace, BUTTON_BACK);
	VGlobal::p()->Input->SetButtonInput("Start", sf::Keyboard::Return, BUTTON_START);
#elif defined(USE_SFML_JOYSTICK)
	VGlobal::p()->Input->SetAxisInput("leftX", sf::Keyboard::D, sf::Keyboard::A, sf::Joystick::Axis::X);
	VGlobal::p()->Input->SetAxisInput("leftY", sf::Keyboard::S, sf::Keyboard::W, sf::Joystick::Axis::Y);
	VGlobal::p()->Input->SetAxisInput("rightX", sf::Keyboard::L, sf::Keyboard::J, sf::Joystick::Axis::U);
	VGlobal::p()->Input->SetAxisInput("rightY", sf::Keyboard::K, sf::Keyboard::I, sf::Joystick::Axis::R);
	VGlobal::p()->Input->SetAxisInput("LT", sf::Keyboard::E, sf::Keyboard::Q, sf::Joystick::Axis::Z);
	VGlobal::p()->Input->SetAxisInput("RT", sf::Keyboard::O, sf::Keyboard::U, sf::Joystick::Axis::Z);
	VGlobal::p()->Input->SetButtonInput("A", sf::Keyboard::N, VInputHandler::BUTTON_A);
	VGlobal::p()->Input->SetButtonInput("B", sf::Keyboard::M, VInputHandler::BUTTON_B);
	VGlobal::p()->Input->SetButtonInput("X", sf::Keyboard::H, VInputHandler::BUTTON_X);
	VGlobal::p()->Input->SetButtonInput("Y", sf::Keyboard::J, VInputHandler::BUTTON_Y);
	VGlobal::p()->Input->SetButtonInput("leftShoulder", sf::Keyboard::T, VInputHandler::BUTTON_LEFT_SHOULDER);
	VGlobal::p()->Input->SetButtonInput("rightShoulder", sf::Keyboard::Y, VInputHandler::BUTTON_RIGHT_SHOULDER);
	VGlobal::p()->Input->SetButtonInput("leftStick", sf::Keyboard::B, VInputHandler::BUTTON_LEFT_THUMB);
	VGlobal::p()->Input->SetButtonInput("rightStick", sf::Keyboard::N, VInputHandler::BUTTON_RIGHT_THUMB);
	VGlobal::p()->Input->SetButtonInput("Back", sf::Keyboard::BackSpace, VInputHandler::BUTTON_BACK);
	VGlobal::p()->Input->SetButtonInput("Start", sf::Keyboard::Return, VInputHandler::BUTTON_START);
	VGlobal::p()->Input->SetButtonInput("Home", sf::Keyboard::Home, VInputHandler::BUTTON_HOME);
#else
	VGlobal::p()->Input->SetAxisInput("leftX", sf::Keyboard::D, sf::Keyboard::A, sf::XInputDevice::XAxis::PovX);
	VGlobal::p()->Input->SetAxisInput("leftY", sf::Keyboard::S, sf::Keyboard::W, sf::XInputDevice::XAxis::PovY);
	VGlobal::p()->Input->SetAxisInput("rightX", sf::Keyboard::L, sf::Keyboard::J, sf::XInputDevice::XAxis::Z);
	VGlobal::p()->Input->SetAxisInput("rightY", sf::Keyboard::K, sf::Keyboard::I, sf::XInputDevice::XAxis::V);
	VGlobal::p()->Input->SetAxisInput("LT", sf::Keyboard::E, sf::Keyboard::Q, sf::XInputDevice::XAxis::L);
	VGlobal::p()->Input->SetAxisInput("RT", sf::Keyboard::O, sf::Keyboard::U, sf::XInputDevice::XAxis::R);
	VGlobal::p()->Input->SetButtonInput("A", sf::Keyboard::N, sf::XInputDevice::A);
	VGlobal::p()->Input->SetButtonInput("B", sf::Keyboard::M, sf::XInputDevice::B);
	VGlobal::p()->Input->SetButtonInput("X", sf::Keyboard::H, sf::XInputDevice::X);
	VGlobal::p()->Input->SetButtonInput("Y", sf::Keyboard::J, sf::XInputDevice::Y);
	VGlobal::p()->Input->SetButtonInput("leftShoulder", sf::Keyboard::T, sf::XInputDevice::LB);
	VGlobal::p()->Input->SetButtonInput("rightShoulder", sf::Keyboard::Y, sf::XInputDevice::RB);
	VGlobal::p()->Input->SetButtonInput("leftStick", sf::Keyboard::B, sf::XInputDevice::LEFT_THUMB);
	VGlobal::p()->Input->SetButtonInput("rightStick", sf::Keyboard::N, sf::XInputDevice::RIGHT_THUMB);
	VGlobal::p()->Input->SetButtonInput("Back", sf::Keyboard::BackSpace, sf::XInputDevice::BACK);
	VGlobal::p()->Input->SetButtonInput("Start", sf::Keyboard::Return, sf::XInputDevice::START);
#endif
}

void DemoStatesManager::Update(float dt)
{
	VSUPERCLASS::Update(dt);

#ifdef _DEBUG
	if (debugTimer->Seconds() > 1)
	{
		debugMessages->Text = "FPS: " + std::to_string(static_cast<int>(1.0f / dt)) + " - Objects: " + std::to_string(VBase::DebugObjectCount);
		debugMessages->ApplyChanges();
		debugTimer->Restart();
	}
#endif
}

void DemoStatesManager::HandleEvents(const sf::Event& event)
{
	VSUPERCLASS::HandleEvents(event);

	if (event.type == sf::Event::KeyPressed)
	{
		if (!VGlobal::p()->Async->ActiveAsyncFunctions())
		{
			if (event.key.code == sf::Keyboard::Left)
			{
				CurrentPage--;

				if (CurrentPage < 0)
					CurrentPage = NUM_DEMOPAGES - 1;

				SetNewPage();
			}

			if (event.key.code == sf::Keyboard::Right)
			{
				CurrentPage++;
				CurrentPage %= NUM_DEMOPAGES;

				SetNewPage();
			}
		}

#ifdef _DEBUG
		if (event.key.code == sf::Keyboard::Q)
		{
			VGlobal::p()->DrawDebug = !VGlobal::p()->DrawDebug;
		}
#endif

		if (event.key.code == sf::Keyboard::E)
		{
			VGlobal::p()->Antialiasing = !VGlobal::p()->Antialiasing;
		}

		if (event.key.code == sf::Keyboard::F)
		{
			VGlobal::p()->ToggleFullscreen();
		}
	}
}
<|endoftext|>


<commit_before>#include <boost/tokenizer.hpp>
#include <iostream>
#include <unistd.h>
#include <string.h>
#include <cstdlib>
#include <errno.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string>
#include <sstream>
#include <vector>
#include <sys/stat.h>
#include <fcntl.h>

int oldstdin = dup(0);
int oldstdout = dup(1);
int oldstderr = dup(2);

using namespace std;
using namespace boost;

void execvp(char **ye, int k) {
	ye[k] = NULL;
        int pid = fork();
        if(pid == -1) {
       		perror("fork");
                exit(1);
        }
        if(pid == 0) {
        	int r = execvp(ye[0], ye);
                if(r == -1) {
                       perror("execvp");
                       exit(1);
                }
        }
      	else {
        	if(-1 == waitpid(pid, &pid, 0)) {
                          perror("waitpid");
                }
        }

}

void rshell(string &x) {
	char *argv[9];
	int i = 0;
	string going;
	string saad;
	vector<string> arg_s;
	typedef tokenizer< char_separator<char> > tokenizer;
	char_separator<char> sep (" ", "<>>>\"#-;||&&", drop_empty_tokens);
	tokenizer tokens(x, sep);
	for(tokenizer::iterator tok_iter=tokens.begin(); tok_iter != tokens.end(); ++tok_iter) {			 if(saad == "-") {
			going += *tok_iter;
			going += " ";
		 	saad.append(*tok_iter);
			arg_s.push_back(saad);
			argv[i] = new char[12];
			strcpy(argv[i], const_cast<char*>(saad.c_str()));
			if(*tok_iter == "exit")
				exit(0);
                        ++i;
                        continue;

		  }

                  if(*tok_iter == "-") {
                        saad = *tok_iter;
			going += *tok_iter;
			going += " ";
                        continue;
                  }

	          if(*tok_iter == "#") {
			break;
		  }

		  if(*tok_iter == ";") {
                        ++tok_iter;
                        rshell(going);
                        going.erase(0, going.find(*tok_iter, i));
                        arg_s.clear();
                        i = 0;
                        argv[i] = new char[12];
	          }

		  if(*tok_iter == "&") {
			++tok_iter;
			if(*tok_iter == "&") {
				++tok_iter;
				rshell(going);
				going.erase(0, going.find(*tok_iter, i));
				arg_s.clear();
				i = 0;
				argv[i] = new char[12];
			}
		  }

		  if(*tok_iter == "<") {
			++tok_iter;

			if(*tok_iter == "<") {
			//	going += *tok_iter;
				++tok_iter;
			//	going += *tok_iter;
				if(*tok_iter == "<") {
					//EXTRA CREDIT 1 HERE!!!!!!!!!!!
				//	++tok_iter;
				//	going += *tok_iter;
				//	string leggo;
				//	if(*tok_iter == "\"") {
				//		++tok_iter;
				//		while(*tok_iter != "\"") {
				//			cout << *tok_iter << endl;
				//			leggo += *tok_iter;
				//			leggo += " ";
				//			++tok_iter;
				//		}
				//		leggo += *tok_iter;
				//		going += " ";
				//		going += leggo;
				//	}
				}
			}
			string cake = *tok_iter;
			int fd = open(cake.c_str(), O_RDWR);
			if(fd == -1) {
				perror("open");
				exit(1);
			}
			int drag = dup2(fd, 0);
			if(drag == -1) {
				perror("dup2");
				exit(1);
			}
			continue;
		  }

		  if(*tok_iter == ">") {
			++tok_iter;
			if(*tok_iter == ">") {
				++tok_iter;
				string swerve = *tok_iter;
				int fd2 = open(swerve.c_str(), O_RDWR|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR);
				if(fd2 == -1) {
					perror("open");
					exit(1);
				}
				int grag = dup2(fd2, 1);
				if(grag == -1) {
					perror("dup2");
					exit(1);
				}
				continue;
			}
			else {
				string hold = *tok_iter;
				int fd = open(hold.c_str(), O_RDWR|O_CREAT|O_TRUNC, S_IRUSR | S_IWUSR);
				if(fd == -1) {
					perror("open");
					exit(1);
				}
				int drag = dup2(fd, 1);
				if(drag == -1) {
					perror("dup2");
					exit(1);
				}
				continue;
			}
		  }

		  if(*tok_iter == "|") {
			++tok_iter;
			if(*tok_iter != "|") {
			//piping
			int pipefd[2];
			pid_t cpid;
			//char buf;
			if(pipe(pipefd) == -1) {
				perror("pipe");
				exit(1);
			}
			cpid = fork();
			if(cpid == -1) {
				perror("fork");
				exit(1);
			}
			else if(cpid == 0) {
				if(-1 == dup2(pipefd[1],1))
				{
					perror("dup2");
					exit(1);
				}
				if(-1 == close(pipefd[0]))
				{
					perror("close");
					exit(1);
				}
				argv[i] = NULL;
				if(-1 == execvp(argv[0], argv))
				{
					perror("execvp");
				}
				exit(1);
			}
			else if(cpid > 0)
			{
				int savestdin;
				if(-1 == (savestdin = dup(0)))
				{
					perror("dup");
					exit(1);
				}
				if(-1 == dup2(pipefd[0], 0)) {
					perror("dup2");
					exit(1);
				}
				if(-1 == close(pipefd[1])) {
					perror("close");
					exit(1);
				}
				if(-1 == waitpid(cpid, &cpid, 0)) {
					perror("waitpid");
					exit(1);
				}
				char *toby[9];
				int l = 0;
				vector<string> baby;
				string mok;
				int kpid = fork();
				if(kpid == -1) {
					perror("fork");
					exit(1);
				}
				else if(kpid == 0) {
					if(-1 == dup2(pipefd[0], 0)) {
						perror("dup2");
						exit(1);
					}
					if(-1 == close(pipefd[1]))
					{
						perror("close");
						exit(1);
					}
					while(tok_iter != tokens.end()) {
						if(*tok_iter == "|")
							rshell(going);

						mok += *tok_iter;
						mok += " ";
						baby.push_back(*tok_iter);
						toby[l] = new char[12];
						strcpy(toby[i], const_cast<char*>(baby[l].c_str()));
						going += mok;
						//APPEND TOBY TO ARGV SOMEHOW
						++l;
					}
				}

			}
			}
			//end piping

			if(*tok_iter == "|") {
				++tok_iter;
				rshell(going);
				going.erase(0, going.find(*tok_iter, i));
				arg_s.clear();
				i = 0;
				argv[i] = new char[12];
			}

		  }

		  going += *tok_iter;
		  going += " ";

		  arg_s.push_back(*tok_iter);
		  argv[i] = new char[12];
	 	  strcpy(argv[i], const_cast<char*>(arg_s[i].c_str()));

		  if(*tok_iter == "exit")
			exit(0);

		  ++i;

	}

	execvp(argv, i);

	return;
}

int main()
{
	string args;
	while(1 != 2)
	{
		cout << "$ ";
		getline(cin, args);
		rshell(args);

		int ok = dup2(oldstdin, 0);
		if(ok == -1) {
			perror("dup2");
			exit(1);
		}
		int ok2 = dup2(oldstdout, 1);
		if(ok2 == -1) {
			perror("dup2");
			exit(1);
		}
		int ok3 = dup2(oldstderr, 2);
		if(ok3 == -1) {
			perror("dup2");
			exit(1);
		}
	}

	return 0;
}
<commit_msg>rshell updated<commit_after>#include <boost/tokenizer.hpp>
#include <iostream>
#include <unistd.h>
#include <string.h>
#include <cstdlib>
#include <errno.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string>
#include <sstream>
#include <vector>
#include <sys/stat.h>
#include <fcntl.h>

int oldstdin = dup(0);
int oldstdout = dup(1);
int oldstderr = dup(2);

using namespace std;
using namespace boost;

void execvp(char **ye, int k) {
	ye[k] = NULL;
        int pid = fork();
        if(pid == -1) {
       		perror("fork");
                exit(1);
        }
        if(pid == 0) {
        	int r = execvp(ye[0], ye);
                if(r == -1) {
                       perror("execvp");
                       exit(1);
                }
        }
      	else {
        	if(-1 == waitpid(pid, &pid, 0)) {
                          perror("waitpid");
                }
        }

}

void rshell(string &x) {
	char *argv[9];
	int i = 0;
	string going;
	string saad;
	vector<string> arg_s;
	typedef tokenizer< char_separator<char> > tokenizer;
	char_separator<char> sep (" ", "<>>>\"#-;||&&", drop_empty_tokens);
	tokenizer tokens(x, sep);
	for(tokenizer::iterator tok_iter=tokens.begin(); tok_iter != tokens.end(); ++tok_iter) {			 if(saad == "-") {
			going += *tok_iter;
			going += " ";
		 	saad.append(*tok_iter);
			arg_s.push_back(saad);
			argv[i] = new char[12];
			strcpy(argv[i], const_cast<char*>(saad.c_str()));
			if(*tok_iter == "exit")
				exit(0);
                        ++i;
                        continue;

		  }

                  if(*tok_iter == "-") {
                        saad = *tok_iter;
			going += *tok_iter;
			going += " ";
                        continue;
                  }

	          if(*tok_iter == "#") {
			break;
		  }

		  if(*tok_iter == ";") {
                        ++tok_iter;
                        rshell(going);
                        going.erase(0, going.find(*tok_iter, i));
                        arg_s.clear();
                        i = 0;
                        argv[i] = new char[12];
	          }

		  if(*tok_iter == "&") {
			++tok_iter;
			if(*tok_iter == "&") {
				++tok_iter;
				rshell(going);
				going.erase(0, going.find(*tok_iter, i));
				arg_s.clear();
				i = 0;
				argv[i] = new char[12];
			}
		  }

		  if(*tok_iter == "<") {
			++tok_iter;

			if(*tok_iter == "<") {
			//	going += *tok_iter;
				++tok_iter;
			//	going += *tok_iter;
				if(*tok_iter == "<") {
					//EXTRA CREDIT 1 HERE!!!!!!!!!!!
					string blah = "ok";
					void *buf;
					int fd2 = creat(const_cast<char*>(blah.c_str()), S_IRWXU);
					if(fd2 == -1) {
						perror("creat");
						exit(1);
					}
					++tok_iter;
					going += *tok_iter;
					string leggo;
					if(*tok_iter == "\"") {
						++tok_iter;
						while(*tok_iter != "\"") {
							cout << *tok_iter << endl;
							leggo += *tok_iter;
							leggo += " ";
							++tok_iter;
						}
						buf = malloc(leggo.length());
						//leggo += *tok_iter;
						//going += " ";
						//going += leggo;
						int bag = write(fd2, buf, leggo.length());
						if(bag == -1) {
							perror("write");
							exit(1);
						}
					}
				}
			}
			string cake = *tok_iter;
			int savestdin;
			if(-1 == (savestdin = dup(0))) {
				perror("dup");
				exit(1);
			}
			int fd = open(cake.c_str(), O_RDWR);
			if(fd == -1) {
				perror("open");
				exit(1);
			}
			int drag = dup2(fd, 0);
			if(drag == -1) {
				perror("dup2");
				exit(1);
			}
			//if(-1 == dup2(savestdin, 0))
			//{
			//	perror("dup2");
			//	exit(1);
			//}
			continue;
		  }

		  if(*tok_iter == ">") {
			++tok_iter;
			if(*tok_iter == ">") {
				++tok_iter;
				string swerve = *tok_iter;
				int fd2 = open(swerve.c_str(), O_RDWR|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR);
				if(fd2 == -1) {
					perror("open");
					exit(1);
				}
				int grag = dup2(fd2, 1);
				if(grag == -1) {
					perror("dup2");
					exit(1);
				}
				continue;
			}
			else {
				string hold = *tok_iter;
				int fd = open(hold.c_str(), O_RDWR|O_CREAT|O_TRUNC, S_IRUSR | S_IWUSR);
				if(fd == -1) {
					perror("open");
					exit(1);
				}
				int drag = dup2(fd, 1);
				if(drag == -1) {
					perror("dup2");
					exit(1);
				}
				continue;
			}
		  }

		  if(*tok_iter == "|") {
			++tok_iter;
			tokenizer::iterator coward;
			if(*tok_iter != "|") {
			//piping
			int pipefd[2];
			pid_t cpid;
			//char buf;
			if(pipe(pipefd) == -1) {
				perror("pipe");
				exit(1);
			}
			cpid = fork();
			if(cpid == -1) {
				perror("fork");
				exit(1);
			}
			else if(cpid == 0) {
				if(-1 == dup2(pipefd[1],1))
				{
					perror("dup2");
					exit(1);
				}
				if(-1 == close(pipefd[0]))
				{
					perror("close");
					exit(1);
				}
				argv[i] = NULL;
				if(-1 == execvp(argv[0], argv))
				{
					perror("execvp");
				}
				exit(1);
			}
			else if(cpid > 0)
			{
				int savestdin;
				if(-1 == (savestdin = dup(0)))
				{
					perror("dup");
					exit(1);
				}
				if(-1 == dup2(pipefd[0], 0)) {
					perror("dup2");
					exit(1);
				}
				if(-1 == close(pipefd[1])) {
					perror("close");
					exit(1);
				}
				if(-1 == waitpid(cpid, &cpid, 0)) {
					perror("waitpid");
					exit(1);
				}
				int pipefd2[2];
				pid_t cpid2;
				if(pipe(pipefd2) == -1) {
					perror("pipe");
					exit(1);
				}
				cpid2 = fork();
				if(cpid2 == -1) {
					perror("fork");
					exit(1);
				}
				else if(cpid2 == 0) {
					if(-1 == dup2(pipefd2[0], 0))
					{
						perror("dup2");
						exit(1);
					}
					if(-1 == close(pipefd2[1]))
					{
						perror("close");
						exit(1);
					}
					coward = tok_iter;
					char *toby[9];
					int l = 0;
					vector<string> baby;
					string mok;
					while(tok_iter != tokens.end()) {
						if(*tok_iter == "|")
							rshell(going);

						mok += *tok_iter;
						mok += " ";
						baby.push_back(*tok_iter);
						toby[l] = new char [12];
						strcpy(toby[l], const_cast<char*>(baby[l].c_str()));
						going += mok;
						++l;
					}
					toby[l] = NULL;
					if(-1 == execvp(toby[0], toby))
						perror("execvp");

					exit(1);
				}
				else if(cpid > 0) {
					int savestdout;
					if(-1 == (savestdout = dup(1)))
					{
						perror("dup");
						exit(1);
					}
					if(-1 == dup2(pipefd2[1], 1)) {
						perror("dup2");
						exit(1);
					}
					if(-1 == close(pipefd2[0])) {
						perror("close");
						exit(1);
					}
					if(-1 == waitpid(cpid2, &cpid2, 0)) {
						perror("waitpid");
						exit(1);
					}
					if(-1 == dup2(savestdout, 1))
						perror("dup2");
				}
					if(-1 == dup2(savestdin, 0))
						perror("dup2");
				}
				/*
				coward = tok_iter;
				char *toby[9];
				int l = 0;
				vector<string> baby;
				string mok;
				int kpid = fork();
				if(kpid == -1) {
					perror("fork");
					exit(1);
				}
				else if(kpid == 0) {
					if(-1 == dup2(pipefd[0], 0)) {
						perror("dup2");
						exit(1);
					}
					//if(-1 == close(pipefd[1]))
					//{
					//	perror("close");
					//	exit(1);
					//}
					while(tok_iter != tokens.end()) {
						if(*tok_iter == "|")
							rshell(going);

						mok += *tok_iter;
						mok += " ";
						baby.push_back(*tok_iter);
						toby[l] = new char[12];
						strcpy(toby[i], const_cast<char*>(baby[l].c_str()));
						going += mok;
						//APPEND TOBY TO ARGV SOMEHOW
						++l;
					}
					toby[l] = NULL;
					if(-1 == execvp(toby[0], toby)) {
						perror("execvp");
					}
					exit(1);
				}
				else if(kpid > 0) {
					if(-1 == waitpid(kpid, &kpid, 0)) {
						perror("waitpid");
						exit(1);
					}
				}

				tok_iter = coward;

				if(-1 == dup2(savestdin, 0)) {
					perror("dup2");
					exit(1);
				}
				}
				continue;
				*/
			}
			//end piping

			if(*tok_iter == "|") {
				++tok_iter;
				rshell(going);
				going.erase(0, going.find(*tok_iter, i));
				arg_s.clear();
				i = 0;
				argv[i] = new char[12];
			}

		  }

		  going += *tok_iter;
		  going += " ";

		  arg_s.push_back(*tok_iter);
		  argv[i] = new char[12];
	 	  strcpy(argv[i], const_cast<char*>(arg_s[i].c_str()));

		  if(*tok_iter == "exit")
			exit(0);

		  ++i;

	}

	execvp(argv, i);

	return;
}

int main()
{
	string args;
	while(1 != 2)
	{
		cout << "$ ";
		getline(cin, args);
		rshell(args);

		int ok = dup2(oldstdin, 0);
		if(ok == -1) {
			perror("dup2");
			exit(1);
		}
		int ok2 = dup2(oldstdout, 1);
		if(ok2 == -1) {
			perror("dup2");
			exit(1);
		}
		int ok3 = dup2(oldstderr, 2);
		if(ok3 == -1) {
			perror("dup2");
			exit(1);
		}
	}

	return 0;
}
<|endoftext|>