<commit_before>#ifndef _TILES_HPP_
#define _TILES_HPP_

#include <boost/array.hpp>
#include <boost/pool/pool.hpp>
#include <boost/utility.hpp>

#include <iostream>
#include <vector>

#include "tiles/ManhattanDistance.hpp"
#include "tiles/TilesState.hpp"
#include "tiles/TilesNode.hpp"

class TilesInstance15 : boost::noncopyable
{
public:
  static const unsigned num_abstraction_levels = 8;

  typedef std::pair<Tile, TileCost> TileCostPair;
  typedef boost::array<
    boost::array<bool, 17>,
    num_abstraction_levels + 1
    > AbstractionOrder;

public:
  TilesInstance15 (const TilesState15 &start, const TilesState15 &goal);

  void print(std::ostream &o) const;

  inline bool is_goal(const TilesState15 &s) const
  {
    return s == goal;
  }

  inline TileCost get_epsilon(const TilesState15 &s) const
  {
    return 1;
  }

  /**
   * Expands the given node into the given vector for successors.
   *
   * Note that this does not assign the h values for the successor
   * nodes: that must be done by the caller.
   */
  void compute_successors(const TilesNode15 &n,
                          std::vector<TilesNode15 *> &succs,
                          boost::pool<> &node_pool);

  /**
   * Expands the given node into the given vector for predecessors.
   *
   * For tiles, this method merely calls compute_successors.  With
   * tiles, the moves are all reversible.
   *
   * Note that this does not assign the h values for the predecessor
   * nodes: that must be done by the caller.
   *
   */
  void compute_predecessors(const TilesNode15 &n,
                            std::vector<TilesNode15 *> &succs,
                            boost::pool<> &node_pool);

  void compute_macro_successors(const TilesNode15 &n,
                                std::vector<TilesNode15 *> &succs,
                                boost::pool<> &node_pool);

  void compute_macro_predecessors(const TilesNode15 &n,
                                  std::vector<TilesNode15 *> &succs,
                                  boost::pool<> &node_pool);

  void compute_glued_successors(const TilesNode15 &n,
				std::vector<TilesNode15 *> &succs,
				Tile glued,
				boost::pool<> &node_pool);
  /**
   * Computes and assigns the heuristic for the given child node.
   */
  void compute_heuristic(const TilesNode15 &parent,
                         TilesNode15 &child) const;

  void compute_heuristic(TilesNode15 &child) const;

  const TilesState15 & get_start_state() const;

  const TilesState15 & get_goal_state() const;

  TilesState15 abstract(unsigned level, const TilesState15 &s) const;

  static bool is_valid_level(const unsigned level);

  // Set the abstraction order
  void set_abstraction_order(const AbstractionOrder ord) {
    abstraction_order = ord;
  }

  // Get the Manhattan distance heuristic.
  const ManhattanDist15 get_md(void) {
    return md_heur;
  }

  unsigned find_tile_index(const std::vector<TileCostPair> &pairs,
                           Tile t) const;

  bool should_abstract(unsigned level, Tile t) const;

private:
  TilesNode15 * child(const TilesState15 &new_state,
                      TileCost new_g,
                      const TilesNode15 &parent,
                      boost::pool<> &node_pool);

  AbstractionOrder compute_abstraction_order(const TilesState15 &s,
                                             const ManhattanDist15 &md) const;

  void dump_abstraction_order(std::ostream &o) const;

  static bool valid_level(unsigned level);

private:
  const TilesState15 start;
  const TilesState15 goal;

  const ManhattanDist15 md_heur;
  AbstractionOrder abstraction_order;
};

std::ostream & operator << (std::ostream &o, const TilesInstance15 &t);
TilesInstance15 * readTilesInstance15 (std::istream &in);

#endif	/* !_TILES_HPP_ */
<commit_msg>a comment about AbstractionOrder representation<commit_after>#ifndef _TILES_HPP_
#define _TILES_HPP_

#include <boost/array.hpp>
#include <boost/pool/pool.hpp>
#include <boost/utility.hpp>

#include <iostream>
#include <vector>

#include "tiles/ManhattanDistance.hpp"
#include "tiles/TilesState.hpp"
#include "tiles/TilesNode.hpp"

class TilesInstance15 : boost::noncopyable
{
public:
  static const unsigned num_abstraction_levels = 8;

  typedef std::pair<Tile, TileCost> TileCostPair;
  /*! \brief An AbstractionOrder indicates which tiles should be obscured
      at each level in an abstraction hierarchy.

      Given an AbstractionOrder `order`, A tile `t` should be abstracted at
      level `i` if and only if `order[i][t + 1]` is true.  Why `t + 1`?
      Because the value -1 is used to represent an obscured tile, and
      boost::array is indexed from 0.
   */
  typedef boost::array<
    boost::array<bool, 17>,
    num_abstraction_levels + 1
    > AbstractionOrder;

public:
  TilesInstance15 (const TilesState15 &start, const TilesState15 &goal);

  void print(std::ostream &o) const;

  inline bool is_goal(const TilesState15 &s) const
  {
    return s == goal;
  }

  inline TileCost get_epsilon(const TilesState15 &s) const
  {
    return 1;
  }

  /**
   * Expands the given node into the given vector for successors.
   *
   * Note that this does not assign the h values for the successor
   * nodes: that must be done by the caller.
   */
  void compute_successors(const TilesNode15 &n,
                          std::vector<TilesNode15 *> &succs,
                          boost::pool<> &node_pool);

  /**
   * Expands the given node into the given vector for predecessors.
   *
   * For tiles, this method merely calls compute_successors.  With
   * tiles, the moves are all reversible.
   *
   * Note that this does not assign the h values for the predecessor
   * nodes: that must be done by the caller.
   *
   */
  void compute_predecessors(const TilesNode15 &n,
                            std::vector<TilesNode15 *> &succs,
                            boost::pool<> &node_pool);

  void compute_macro_successors(const TilesNode15 &n,
                                std::vector<TilesNode15 *> &succs,
                                boost::pool<> &node_pool);

  void compute_macro_predecessors(const TilesNode15 &n,
                                  std::vector<TilesNode15 *> &succs,
                                  boost::pool<> &node_pool);

  void compute_glued_successors(const TilesNode15 &n,
				std::vector<TilesNode15 *> &succs,
				Tile glued,
				boost::pool<> &node_pool);
  /**
   * Computes and assigns the heuristic for the given child node.
   */
  void compute_heuristic(const TilesNode15 &parent,
                         TilesNode15 &child) const;

  void compute_heuristic(TilesNode15 &child) const;

  const TilesState15 & get_start_state() const;

  const TilesState15 & get_goal_state() const;

  TilesState15 abstract(unsigned level, const TilesState15 &s) const;

  static bool is_valid_level(const unsigned level);

  // Set the abstraction order
  void set_abstraction_order(const AbstractionOrder ord) {
    abstraction_order = ord;
  }

  // Get the Manhattan distance heuristic.
  const ManhattanDist15 get_md(void) {
    return md_heur;
  }

  unsigned find_tile_index(const std::vector<TileCostPair> &pairs,
                           Tile t) const;

  bool should_abstract(unsigned level, Tile t) const;

private:
  TilesNode15 * child(const TilesState15 &new_state,
                      TileCost new_g,
                      const TilesNode15 &parent,
                      boost::pool<> &node_pool);

  AbstractionOrder compute_abstraction_order(const TilesState15 &s,
                                             const ManhattanDist15 &md) const;

  void dump_abstraction_order(std::ostream &o) const;

  static bool valid_level(unsigned level);

private:
  const TilesState15 start;
  const TilesState15 goal;

  const ManhattanDist15 md_heur;
  AbstractionOrder abstraction_order;
};

std::ostream & operator << (std::ostream &o, const TilesInstance15 &t);
TilesInstance15 * readTilesInstance15 (std::istream &in);

#endif	/* !_TILES_HPP_ */
<|endoftext|>


<commit_before>#include <bashclass/IBType.h>
#include <bashclass/BElementType.h>

/*********************
 *  TOKEN TYPE NAME
 *********************/
const std::string IBType::TYPE_NAME_INT = "int_type";
const std::string IBType::TYPE_NAME_CHAR = "char_type";
const std::string IBType::TYPE_NAME_BOOLEAN = "boolean_type";
const std::string IBType::TYPE_NAME_VOID = "void_type";
const std::string IBType::TYPE_NAME_IDENTIFIER = "identifier";

/*********************
 *  TOKEN TYPE VALUE
 *********************/
const std::string IBType::TYPE_VALUE_INT = "int";
const std::string IBType::TYPE_VALUE_CHAR = "char";
const std::string IBType::TYPE_VALUE_BOOLEAN = "boolean";
const std::string IBType::TYPE_VALUE_VOID = "void";

/*********************
 *  TOKEN TYPE DATA
 *********************/
const std::string IBType::DATA_TYPE_NAME_INT = "integer";
const std::string IBType::DATA_TYPE_NAME_CHAR = "character";
const std::string IBType::DATA_TYPE_NAME_BOOLEAN = "truefalse";
const std::string IBType::DATA_TYPE_NAME_STRING = "string_literal";
const std::string IBType::DATA_TYPE_NAME_BASH_SUB = "bash_sub";
const std::string IBType::DATA_TYPE_NAME_BASH_INLINE = "bash_inline";
const std::string IBType::DATA_TYPE_NAME_BASH_BLOCK = "bash_block";

/*********************
 * SPECIAL TOKEN TYPE
 *********************/
const std::string IBType::UNDEFINED = "undefined";
const std::string IBType::NULL_VALUE = "null";

bool IBType::isBuiltInType() {
    return isInt() || isVoid() || isBoolean() || isChar();
}

bool IBType::hasKnownType() {
    return isBuiltInType() || (isIdentifier() && m_typeScope);
}

bool IBType::isCompatible(std::shared_ptr<IBType> type) {

    if(type->isUndefined() || type->isVoid()) {
        return false;
    }

    if((isIdentifier() && type->isNull())) {
        return true;
    }

    if(isArray() && type->isNull()) {
        return true;
    }

    if(getTypeValue() != type->getTypeValue()) {
        return false;
    }

    return getDimension() == type->getDimension();
}

std::string IBType::toString() {
    std::string result = getTypeValue();
    int tmpDim = m_dimension;
    while (tmpDim-- > 0) {
        result += "[]";
    }
    return result;
}

void IBType::cast(std::shared_ptr<BElementType> type) {
    m_dimension = type->getDimension();
    m_typeScope = type->getTypeScope();
}<commit_msg>Enhanced type checking<commit_after>#include <bashclass/IBType.h>
#include <bashclass/BElementType.h>

/*********************
 *  TOKEN TYPE NAME
 *********************/
const std::string IBType::TYPE_NAME_INT = "int_type";
const std::string IBType::TYPE_NAME_CHAR = "char_type";
const std::string IBType::TYPE_NAME_BOOLEAN = "boolean_type";
const std::string IBType::TYPE_NAME_VOID = "void_type";
const std::string IBType::TYPE_NAME_IDENTIFIER = "identifier";

/*********************
 *  TOKEN TYPE VALUE
 *********************/
const std::string IBType::TYPE_VALUE_INT = "int";
const std::string IBType::TYPE_VALUE_CHAR = "char";
const std::string IBType::TYPE_VALUE_BOOLEAN = "boolean";
const std::string IBType::TYPE_VALUE_VOID = "void";

/*********************
 *  TOKEN TYPE DATA
 *********************/
const std::string IBType::DATA_TYPE_NAME_INT = "integer";
const std::string IBType::DATA_TYPE_NAME_CHAR = "character";
const std::string IBType::DATA_TYPE_NAME_BOOLEAN = "truefalse";
const std::string IBType::DATA_TYPE_NAME_STRING = "string_literal";
const std::string IBType::DATA_TYPE_NAME_BASH_SUB = "bash_sub";
const std::string IBType::DATA_TYPE_NAME_BASH_INLINE = "bash_inline";
const std::string IBType::DATA_TYPE_NAME_BASH_BLOCK = "bash_block";

/*********************
 * SPECIAL TOKEN TYPE
 *********************/
const std::string IBType::UNDEFINED = "undefined";
const std::string IBType::NULL_VALUE = "null";

bool IBType::isBuiltInType() {
    return isInt() || isVoid() || isBoolean() || isChar();
}

bool IBType::hasKnownType() {
    return isBuiltInType() || (isIdentifier() && m_typeScope);
}

bool IBType::isCompatible(std::shared_ptr<IBType> type) {

    if(type->isUndefined() || type->isVoid()) {
        return false;
    }

    if(isArray() && type->isNull()) {
        return true;
    }

    if(isIdentifier() && type->isNull()) {
        return true;
    }

    if(isIdentifier() && getTypeScope()
       && type->isIdentifier() && type->getTypeScope()
       && type->getTypeScope()->inheritsFrom(getTypeScope())) {
        return true;
    }

    if(getTypeValue() != type->getTypeValue()) {
        return false;
    }

    return getDimension() == type->getDimension();
}

std::string IBType::toString() {
    std::string result = getTypeValue();
    int tmpDim = m_dimension;
    while (tmpDim-- > 0) {
        result += "[]";
    }
    return result;
}

void IBType::cast(std::shared_ptr<BElementType> type) {
    m_dimension = type->getDimension();
    m_typeScope = type->getTypeScope();
}<|endoftext|>


<commit_before>//
// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

#include <string.h>
#include <cassert>
#include <vector>

#include "EGLWindow.h"
#include "OSWindow.h"
#include "common/debug.h"

#ifdef _WIN32
#elif __linux__
#else
#error unsupported OS.
#endif

EGLPlatformParameters::EGLPlatformParameters()
    : renderer(EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE),
      majorVersion(EGL_DONT_CARE),
      minorVersion(EGL_DONT_CARE),
      deviceType(EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE)
{
}

EGLPlatformParameters::EGLPlatformParameters(EGLint renderer)
    : renderer(renderer),
      majorVersion(EGL_DONT_CARE),
      minorVersion(EGL_DONT_CARE),
      deviceType(EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE)
{
}

EGLPlatformParameters::EGLPlatformParameters(EGLint renderer, EGLint majorVersion, EGLint minorVersion, EGLint useWarp)
    : renderer(renderer),
      majorVersion(majorVersion),
      minorVersion(minorVersion),
      deviceType(useWarp)
{
}

EGLWindow::EGLWindow(size_t width, size_t height, EGLint glesMajorVersion, const EGLPlatformParameters &platform)
    : mSurface(EGL_NO_SURFACE),
      mContext(EGL_NO_CONTEXT),
      mDisplay(EGL_NO_DISPLAY),
      mClientVersion(glesMajorVersion),
      mPlatform(platform),
      mWidth(width),
      mHeight(height),
      mRedBits(-1),
      mGreenBits(-1),
      mBlueBits(-1),
      mAlphaBits(-1),
      mDepthBits(-1),
      mStencilBits(-1),
      mMultisample(false),
      mSwapInterval(-1)
{
}

EGLWindow::~EGLWindow()
{
    destroyGL();
}

void EGLWindow::swap()
{
    eglSwapBuffers(mDisplay, mSurface);
}

EGLConfig EGLWindow::getConfig() const
{
    return mConfig;
}

EGLDisplay EGLWindow::getDisplay() const
{
    return mDisplay;
}

EGLSurface EGLWindow::getSurface() const
{
    return mSurface;
}

EGLContext EGLWindow::getContext() const
{
    return mContext;
}

bool EGLWindow::initializeGL(OSWindow *osWindow)
{
    PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(eglGetProcAddress("eglGetPlatformDisplayEXT"));
    if (!eglGetPlatformDisplayEXT)
    {
        return false;
    }

    std::vector<EGLint> displayAttributes;
    displayAttributes.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE);
    displayAttributes.push_back(mPlatform.renderer);
    displayAttributes.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE);
    displayAttributes.push_back(mPlatform.majorVersion);
    displayAttributes.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE);
    displayAttributes.push_back(mPlatform.minorVersion);

    if (mPlatform.renderer == EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE || mPlatform.renderer == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
    {
        displayAttributes.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE);
        displayAttributes.push_back(mPlatform.deviceType);
    }
    displayAttributes.push_back(EGL_NONE);

    mDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, osWindow->getNativeDisplay(), displayAttributes.data());
    if (mDisplay == EGL_NO_DISPLAY)
    {
        destroyGL();
        return false;
    }

    EGLint majorVersion, minorVersion;
    if (!eglInitialize(mDisplay, &majorVersion, &minorVersion))
    {
        destroyGL();
        return false;
    }

    eglBindAPI(EGL_OPENGL_ES_API);
    if (eglGetError() != EGL_SUCCESS)
    {
        destroyGL();
        return false;
    }

    const EGLint configAttributes[] =
    {
        EGL_RED_SIZE,       (mRedBits >= 0)     ? mRedBits     : EGL_DONT_CARE,
        EGL_GREEN_SIZE,     (mGreenBits >= 0)   ? mGreenBits   : EGL_DONT_CARE,
        EGL_BLUE_SIZE,      (mBlueBits >= 0)    ? mBlueBits    : EGL_DONT_CARE,
        EGL_ALPHA_SIZE,     (mAlphaBits >= 0)   ? mAlphaBits   : EGL_DONT_CARE,
        EGL_DEPTH_SIZE,     (mDepthBits >= 0)   ? mDepthBits   : EGL_DONT_CARE,
        EGL_STENCIL_SIZE,   (mStencilBits >= 0) ? mStencilBits : EGL_DONT_CARE,
        EGL_SAMPLE_BUFFERS, mMultisample ? 1 : 0,
        EGL_NONE
    };

    EGLint configCount;
    if (!eglChooseConfig(mDisplay, configAttributes, &mConfig, 1, &configCount) || (configCount != 1))
    {
        destroyGL();
        return false;
    }

    eglGetConfigAttrib(mDisplay, mConfig, EGL_RED_SIZE, &mRedBits);
    eglGetConfigAttrib(mDisplay, mConfig, EGL_GREEN_SIZE, &mGreenBits);
    eglGetConfigAttrib(mDisplay, mConfig, EGL_BLUE_SIZE, &mBlueBits);
    eglGetConfigAttrib(mDisplay, mConfig, EGL_ALPHA_SIZE, &mBlueBits);
    eglGetConfigAttrib(mDisplay, mConfig, EGL_DEPTH_SIZE, &mDepthBits);
    eglGetConfigAttrib(mDisplay, mConfig, EGL_STENCIL_SIZE, &mStencilBits);

    std::vector<EGLint> surfaceAttributes;
    if (strstr(eglQueryString(mDisplay, EGL_EXTENSIONS), "EGL_NV_post_sub_buffer") != nullptr)
    {
        surfaceAttributes.push_back(EGL_POST_SUB_BUFFER_SUPPORTED_NV);
        surfaceAttributes.push_back(EGL_TRUE);
    }

    surfaceAttributes.push_back(EGL_NONE);
    surfaceAttributes.push_back(EGL_NONE);

    mSurface = eglCreateWindowSurface(mDisplay, mConfig, osWindow->getNativeWindow(), &surfaceAttributes[0]);
    if (eglGetError() != EGL_SUCCESS)
    {
        destroyGL();
        return false;
    }
    ASSERT(mSurface != EGL_NO_SURFACE);

    EGLint contextAttibutes[] =
    {
        EGL_CONTEXT_CLIENT_VERSION, mClientVersion,
        EGL_NONE
    };

    mContext = eglCreateContext(mDisplay, mConfig, NULL, contextAttibutes);
    if (eglGetError() != EGL_SUCCESS)
    {
        destroyGL();
        return false;
    }

    eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);
    if (eglGetError() != EGL_SUCCESS)
    {
        destroyGL();
        return false;
    }

    if (mSwapInterval != -1)
    {
        eglSwapInterval(mDisplay, mSwapInterval);
    }

    return true;
}

void EGLWindow::destroyGL()
{
    if (mSurface != EGL_NO_SURFACE)
    {
        assert(mDisplay != EGL_NO_DISPLAY);
        eglDestroySurface(mDisplay, mSurface);
        mSurface = EGL_NO_SURFACE;
    }

    if (mContext != EGL_NO_CONTEXT)
    {
        assert(mDisplay != EGL_NO_DISPLAY);
        eglDestroyContext(mDisplay, mContext);
        mContext = EGL_NO_CONTEXT;
    }

    if (mDisplay != EGL_NO_DISPLAY)
    {
        eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
        eglTerminate(mDisplay);
        mDisplay = EGL_NO_DISPLAY;
    }
}

bool EGLWindow::isGLInitialized() const
{
    return mSurface != EGL_NO_SURFACE &&
           mContext != EGL_NO_CONTEXT &&
           mDisplay != EGL_NO_DISPLAY;
}
<commit_msg>EGLWindow: remove redundant EGL_NONE to finish attrib list.<commit_after>//
// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

#include <string.h>
#include <cassert>
#include <vector>

#include "EGLWindow.h"
#include "OSWindow.h"
#include "common/debug.h"

#ifdef _WIN32
#elif __linux__
#else
#error unsupported OS.
#endif

EGLPlatformParameters::EGLPlatformParameters()
    : renderer(EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE),
      majorVersion(EGL_DONT_CARE),
      minorVersion(EGL_DONT_CARE),
      deviceType(EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE)
{
}

EGLPlatformParameters::EGLPlatformParameters(EGLint renderer)
    : renderer(renderer),
      majorVersion(EGL_DONT_CARE),
      minorVersion(EGL_DONT_CARE),
      deviceType(EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE)
{
}

EGLPlatformParameters::EGLPlatformParameters(EGLint renderer, EGLint majorVersion, EGLint minorVersion, EGLint useWarp)
    : renderer(renderer),
      majorVersion(majorVersion),
      minorVersion(minorVersion),
      deviceType(useWarp)
{
}

EGLWindow::EGLWindow(size_t width, size_t height, EGLint glesMajorVersion, const EGLPlatformParameters &platform)
    : mSurface(EGL_NO_SURFACE),
      mContext(EGL_NO_CONTEXT),
      mDisplay(EGL_NO_DISPLAY),
      mClientVersion(glesMajorVersion),
      mPlatform(platform),
      mWidth(width),
      mHeight(height),
      mRedBits(-1),
      mGreenBits(-1),
      mBlueBits(-1),
      mAlphaBits(-1),
      mDepthBits(-1),
      mStencilBits(-1),
      mMultisample(false),
      mSwapInterval(-1)
{
}

EGLWindow::~EGLWindow()
{
    destroyGL();
}

void EGLWindow::swap()
{
    eglSwapBuffers(mDisplay, mSurface);
}

EGLConfig EGLWindow::getConfig() const
{
    return mConfig;
}

EGLDisplay EGLWindow::getDisplay() const
{
    return mDisplay;
}

EGLSurface EGLWindow::getSurface() const
{
    return mSurface;
}

EGLContext EGLWindow::getContext() const
{
    return mContext;
}

bool EGLWindow::initializeGL(OSWindow *osWindow)
{
    PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(eglGetProcAddress("eglGetPlatformDisplayEXT"));
    if (!eglGetPlatformDisplayEXT)
    {
        return false;
    }

    std::vector<EGLint> displayAttributes;
    displayAttributes.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE);
    displayAttributes.push_back(mPlatform.renderer);
    displayAttributes.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE);
    displayAttributes.push_back(mPlatform.majorVersion);
    displayAttributes.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE);
    displayAttributes.push_back(mPlatform.minorVersion);

    if (mPlatform.renderer == EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE || mPlatform.renderer == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
    {
        displayAttributes.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE);
        displayAttributes.push_back(mPlatform.deviceType);
    }
    displayAttributes.push_back(EGL_NONE);

    mDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, osWindow->getNativeDisplay(), displayAttributes.data());
    if (mDisplay == EGL_NO_DISPLAY)
    {
        destroyGL();
        return false;
    }

    EGLint majorVersion, minorVersion;
    if (!eglInitialize(mDisplay, &majorVersion, &minorVersion))
    {
        destroyGL();
        return false;
    }

    eglBindAPI(EGL_OPENGL_ES_API);
    if (eglGetError() != EGL_SUCCESS)
    {
        destroyGL();
        return false;
    }

    const EGLint configAttributes[] =
    {
        EGL_RED_SIZE,       (mRedBits >= 0)     ? mRedBits     : EGL_DONT_CARE,
        EGL_GREEN_SIZE,     (mGreenBits >= 0)   ? mGreenBits   : EGL_DONT_CARE,
        EGL_BLUE_SIZE,      (mBlueBits >= 0)    ? mBlueBits    : EGL_DONT_CARE,
        EGL_ALPHA_SIZE,     (mAlphaBits >= 0)   ? mAlphaBits   : EGL_DONT_CARE,
        EGL_DEPTH_SIZE,     (mDepthBits >= 0)   ? mDepthBits   : EGL_DONT_CARE,
        EGL_STENCIL_SIZE,   (mStencilBits >= 0) ? mStencilBits : EGL_DONT_CARE,
        EGL_SAMPLE_BUFFERS, mMultisample ? 1 : 0,
        EGL_NONE
    };

    EGLint configCount;
    if (!eglChooseConfig(mDisplay, configAttributes, &mConfig, 1, &configCount) || (configCount != 1))
    {
        destroyGL();
        return false;
    }

    eglGetConfigAttrib(mDisplay, mConfig, EGL_RED_SIZE, &mRedBits);
    eglGetConfigAttrib(mDisplay, mConfig, EGL_GREEN_SIZE, &mGreenBits);
    eglGetConfigAttrib(mDisplay, mConfig, EGL_BLUE_SIZE, &mBlueBits);
    eglGetConfigAttrib(mDisplay, mConfig, EGL_ALPHA_SIZE, &mBlueBits);
    eglGetConfigAttrib(mDisplay, mConfig, EGL_DEPTH_SIZE, &mDepthBits);
    eglGetConfigAttrib(mDisplay, mConfig, EGL_STENCIL_SIZE, &mStencilBits);

    std::vector<EGLint> surfaceAttributes;
    if (strstr(eglQueryString(mDisplay, EGL_EXTENSIONS), "EGL_NV_post_sub_buffer") != nullptr)
    {
        surfaceAttributes.push_back(EGL_POST_SUB_BUFFER_SUPPORTED_NV);
        surfaceAttributes.push_back(EGL_TRUE);
    }

    surfaceAttributes.push_back(EGL_NONE);

    mSurface = eglCreateWindowSurface(mDisplay, mConfig, osWindow->getNativeWindow(), &surfaceAttributes[0]);
    if (eglGetError() != EGL_SUCCESS)
    {
        destroyGL();
        return false;
    }
    ASSERT(mSurface != EGL_NO_SURFACE);

    EGLint contextAttibutes[] =
    {
        EGL_CONTEXT_CLIENT_VERSION, mClientVersion,
        EGL_NONE
    };

    mContext = eglCreateContext(mDisplay, mConfig, NULL, contextAttibutes);
    if (eglGetError() != EGL_SUCCESS)
    {
        destroyGL();
        return false;
    }

    eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);
    if (eglGetError() != EGL_SUCCESS)
    {
        destroyGL();
        return false;
    }

    if (mSwapInterval != -1)
    {
        eglSwapInterval(mDisplay, mSwapInterval);
    }

    return true;
}

void EGLWindow::destroyGL()
{
    if (mSurface != EGL_NO_SURFACE)
    {
        assert(mDisplay != EGL_NO_DISPLAY);
        eglDestroySurface(mDisplay, mSurface);
        mSurface = EGL_NO_SURFACE;
    }

    if (mContext != EGL_NO_CONTEXT)
    {
        assert(mDisplay != EGL_NO_DISPLAY);
        eglDestroyContext(mDisplay, mContext);
        mContext = EGL_NO_CONTEXT;
    }

    if (mDisplay != EGL_NO_DISPLAY)
    {
        eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
        eglTerminate(mDisplay);
        mDisplay = EGL_NO_DISPLAY;
    }
}

bool EGLWindow::isGLInitialized() const
{
    return mSurface != EGL_NO_SURFACE &&
           mContext != EGL_NO_CONTEXT &&
           mDisplay != EGL_NO_DISPLAY;
}
<|endoftext|>


<commit_before>#include "osm2nav.h"
#include <stdio.h>

#include <iostream>
#include <boost/lexical_cast.hpp>
#include "type/data.h"
#include "third_party/osmpbfreader/osmpbfreader.h"
#include "osm_tags_reader.h"
#include "georef/georef.h"

namespace navitia { namespace georef {
struct Node {
public:
    double lon() const {return static_cast<double>(this->lon_m) / precision;}
    double lat() const {return static_cast<double>(this->lat_m) / precision;}
    uint32_t uses;
    int32_t idx;

    Node(double lon = 0, double lat = 0) : uses(0), idx(-1), lon_m(lon * precision), lat_m(lat * precision){}
    bool increment_use(int idx){
        uses++;
        if(this->idx == -1 && uses > 1){
            this->idx = idx;
            return true;
        } else {
            return false;
        }
    }

private:
    int32_t lon_m;
    int32_t lat_m;
    static constexpr double precision = 10e6;
};

struct OSMWay {
    const static uint8_t CYCLE_FWD = 0;
    const static uint8_t CYCLE_BWD = 1;
    const static uint8_t CAR_FWD = 2;
    const static uint8_t CAR_BWD = 3;
    const static uint8_t FOOT_FWD = 4;
    const static uint8_t FOOT_BWD = 5;
    std::vector<uint64_t> refs;
    uint64_t id;
    std::bitset<8> properties;
    type::idx_t idx;
};

using namespace CanalTP;

struct Visitor{
    std::unordered_map<uint64_t, Node> nodes;
    int total_ways;
    std::vector<OSMWay> ways;
    georef::GeoRef & geo_ref;

    Visitor(GeoRef & to_fill) : total_ways(0), geo_ref(to_fill){}

    void node_callback(uint64_t osmid, double lon, double lat, const Tags &/*tags*/){
        this->nodes[osmid] = Node(lon, lat);
    }

    void way_callback(uint64_t osmid, const Tags &tags, const std::vector<uint64_t> &refs){
        total_ways++;
        std::bitset<8> properties = parse_way_tags(tags);
        if(properties.any()){
            OSMWay w;
            w.idx = ways.size();
            w.refs = refs;
            w.id = osmid;
            ways.push_back(w);

            georef::Way gr_way;
            gr_way.idx = w.idx;
            gr_way.city_idx = type::invalid_idx;
            if(tags.find("name") != tags.end())
                gr_way.name = tags.at("name");
            geo_ref.ways.push_back(gr_way);
        }
    }

    // Once all the ways and nodes are read, we count how many times a node is used to detect intersections
    void count_nodes_uses() {
        int count = 0;
        for(auto w : ways){

            for(uint64_t ref : w.refs){
                if(nodes[ref].increment_use(count)){
                    Vertex v;
                    count++;
                    v.coord = type::GeographicalCoord( nodes[ref].lon(), nodes[ref].lat());
                    boost::add_vertex(v, geo_ref.graph);
                }
            }
            // make sure that the last node is considered as an extremity
            if(nodes[w.refs.front()].increment_use(count)){
                count++;
                Vertex v;
                v.coord = type::GeographicalCoord(nodes[w.refs.front()].lon(), nodes[w.refs.front()].lat());
                boost::add_vertex(v, geo_ref.graph);
            }
            if(nodes[w.refs.back()].increment_use(count)){
                count++;
                Vertex v;
                v.coord = type::GeographicalCoord(nodes[w.refs.back()].lon(), nodes[w.refs.back()].lat());
                boost::add_vertex(v, geo_ref.graph);
            }
        }
        std::cout << "On a : " << boost::num_vertices(geo_ref.graph) << " nœuds" << std::endl;
    }

    // Returns the source and target node of the edges
    void edges(){
        for(OSMWay w : ways){
            if(w.refs.size() > 0){
                Node n = nodes[w.refs[0]];
                type::idx_t source = n.idx;
                type::GeographicalCoord prev(n.lon(), n.lat());
                float length = 0;
                for(size_t i = 1; i < w.refs.size(); ++i){
                    Node current_node = nodes[w.refs[i]];
                    type::GeographicalCoord current(current_node.lon(), current_node.lat());
                    length += current.distance_to(prev);
                    prev = current;
                    // If a node is used more than once, it is an intersection, hence it's a node of the road network graph
                    if(current_node.uses > 1){
                        type::idx_t target = current_node.idx;
                        georef::Edge e;
                        e.length = length;
                        e.way_idx = w.idx;
                        e.cyclable = w.properties[CYCLE_FWD];
                        boost::add_edge(source, target, e, geo_ref.graph);
                        e.cyclable = w.properties[CYCLE_BWD];
                        boost::add_edge(target, source, e, geo_ref.graph);
                        source = target;
                        length = 0;
                    }
                }
            }
        }
        std::cout << "On a " << boost::num_edges(geo_ref.graph) << " arcs" << std::endl;
    }

    // We don't care about relations
    void relation_callback(uint64_t /*osmid*/, const Tags &/*tags*/, const References & /*refs*/){}
};

void fill_from_osm(GeoRef & geo_ref_to_fill, const std::string & osm_pbf_filename){
    Visitor v(geo_ref_to_fill);
    CanalTP::read_osm_pbf(osm_pbf_filename, v);
    std::cout << v.nodes.size() << " nodes, " << v.ways.size() << " ways/" << v.total_ways << std::endl;
    v.count_nodes_uses();
    v.edges();
}
}}

<commit_msg>NaviMake : création d'un externalcode pour OSM<commit_after>#include "osm2nav.h"
#include <stdio.h>

#include <iostream>
#include <boost/lexical_cast.hpp>
#include "type/data.h"
#include "third_party/osmpbfreader/osmpbfreader.h"
#include "osm_tags_reader.h"
#include "georef/georef.h"

namespace navitia { namespace georef {
struct Node {
public:
    double lon() const {return static_cast<double>(this->lon_m) / precision;}
    double lat() const {return static_cast<double>(this->lat_m) / precision;}
    uint32_t uses;
    int32_t idx;

    Node(double lon = 0, double lat = 0) : uses(0), idx(-1), lon_m(lon * precision), lat_m(lat * precision){}
    bool increment_use(int idx){
        uses++;
        if(this->idx == -1 && uses > 1){
            this->idx = idx;
            return true;
        } else {
            return false;
        }
    }

private:
    int32_t lon_m;
    int32_t lat_m;
    static constexpr double precision = 10e6;
};

struct OSMWay {
    const static uint8_t CYCLE_FWD = 0;
    const static uint8_t CYCLE_BWD = 1;
    const static uint8_t CAR_FWD = 2;
    const static uint8_t CAR_BWD = 3;
    const static uint8_t FOOT_FWD = 4;
    const static uint8_t FOOT_BWD = 5;
    std::vector<uint64_t> refs;
    uint64_t id;
    std::bitset<8> properties;
    type::idx_t idx;
};

using namespace CanalTP;

struct Visitor{
    std::unordered_map<uint64_t, Node> nodes;
    int total_ways;
    std::vector<OSMWay> ways;
    georef::GeoRef & geo_ref;

    Visitor(GeoRef & to_fill) : total_ways(0), geo_ref(to_fill){}

    void node_callback(uint64_t osmid, double lon, double lat, const Tags &/*tags*/){
        this->nodes[osmid] = Node(lon, lat);
    }

    void way_callback(uint64_t osmid, const Tags &tags, const std::vector<uint64_t> &refs){
        total_ways++;
        std::bitset<8> properties = parse_way_tags(tags);
        if(properties.any()){
            OSMWay w;
            w.idx = ways.size();
            w.refs = refs;
            w.id = osmid;
            ways.push_back(w);

            georef::Way gr_way;
            gr_way.idx = w.idx;
            gr_way.external_code = std::to_string(w.idx);
            gr_way.city_idx = type::invalid_idx;
            if(tags.find("name") != tags.end())
                gr_way.name = tags.at("name");
            geo_ref.ways.push_back(gr_way);
        }
    }

    // Once all the ways and nodes are read, we count how many times a node is used to detect intersections
    void count_nodes_uses() {
        int count = 0;
        for(auto w : ways){

            for(uint64_t ref : w.refs){
                if(nodes[ref].increment_use(count)){
                    Vertex v;
                    count++;
                    v.coord = type::GeographicalCoord( nodes[ref].lon(), nodes[ref].lat());
                    boost::add_vertex(v, geo_ref.graph);
                }
            }
            // make sure that the last node is considered as an extremity
            if(nodes[w.refs.front()].increment_use(count)){
                count++;
                Vertex v;
                v.coord = type::GeographicalCoord(nodes[w.refs.front()].lon(), nodes[w.refs.front()].lat());
                boost::add_vertex(v, geo_ref.graph);
            }
            if(nodes[w.refs.back()].increment_use(count)){
                count++;
                Vertex v;
                v.coord = type::GeographicalCoord(nodes[w.refs.back()].lon(), nodes[w.refs.back()].lat());
                boost::add_vertex(v, geo_ref.graph);
            }
        }
        std::cout << "On a : " << boost::num_vertices(geo_ref.graph) << " nœuds" << std::endl;
    }

    // Returns the source and target node of the edges
    void edges(){
        for(OSMWay w : ways){
            if(w.refs.size() > 0){
                Node n = nodes[w.refs[0]];
                type::idx_t source = n.idx;
                type::GeographicalCoord prev(n.lon(), n.lat());
                float length = 0;
                for(size_t i = 1; i < w.refs.size(); ++i){
                    Node current_node = nodes[w.refs[i]];
                    type::GeographicalCoord current(current_node.lon(), current_node.lat());
                    length += current.distance_to(prev);
                    prev = current;
                    // If a node is used more than once, it is an intersection, hence it's a node of the road network graph
                    if(current_node.uses > 1){
                        type::idx_t target = current_node.idx;
                        georef::Edge e;
                        e.length = length;
                        e.way_idx = w.idx;
                        e.cyclable = w.properties[CYCLE_FWD];
                        boost::add_edge(source, target, e, geo_ref.graph);
                        e.cyclable = w.properties[CYCLE_BWD];
                        boost::add_edge(target, source, e, geo_ref.graph);
                        source = target;
                        length = 0;
                    }
                }
            }
        }
        std::cout << "On a " << boost::num_edges(geo_ref.graph) << " arcs" << std::endl;
    }

    // We don't care about relations
    void relation_callback(uint64_t /*osmid*/, const Tags &/*tags*/, const References & /*refs*/){}
};

void fill_from_osm(GeoRef & geo_ref_to_fill, const std::string & osm_pbf_filename){
    Visitor v(geo_ref_to_fill);
    CanalTP::read_osm_pbf(osm_pbf_filename, v);
    std::cout << v.nodes.size() << " nodes, " << v.ways.size() << " ways/" << v.total_ways << std::endl;
    v.count_nodes_uses();
    v.edges();
}
}}

<|endoftext|>


<commit_before>/*
 * Copyright 2021 Alain Dargelas
 *
 * 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 <errno.h>
#include <limits.h> /* PATH_MAX */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>

#include <algorithm>
#include <fstream>
#include <iostream>
#include <regex>
#include <sstream>
#include <string>

#if !(defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__))
#include <dirent.h>
#include <unistd.h>
#endif

#include "headers/uhdm.h"
#include "headers/vpi_listener.h"

using namespace UHDM;

static int usage(const char* progname) {
  fprintf(stderr, "Usage:\n%s [options] <uhdm-file>\n", progname);
  fprintf(stderr,
          "Reads UHDM binary representation and prints hierarchy tree.\n");
  return 1;
}

int main(int argc, char** argv) {
  std::string uhdmFile;

  // Simple option parsing that works on all platforms.
  for (int i = 1; i < argc; ++i) {
    const std::string arg = argv[i];
    if (uhdmFile.empty())
      uhdmFile = arg;
    else
      return usage(argv[0]);
  }

  if (uhdmFile.empty()) {
    return usage(argv[0]);
  }

  struct stat buffer;
  if (stat(uhdmFile.c_str(), &buffer) != 0) {
    std::cerr << uhdmFile << ": File does not exist!" << std::endl;
    return usage(argv[0]);
  }

  Serializer serializer;
  std::vector<vpiHandle> restoredDesigns = serializer.Restore(uhdmFile);

  if (restoredDesigns.empty()) {
    std::cerr << uhdmFile << ": empty design." << std::endl;
    return 1;
  }
  std::string result;
  for (vpiHandle design : restoredDesigns) {
    if (vpi_get(vpiType, design) == vpiDesign) {
      result +=
          "Design name: " + std::string(vpi_get_str(vpiName, design)) + "\n";
      result += "Instance tree:\n";

      vpiHandle instItr = vpi_iterate(UHDM::uhdmtopModules, design);
      while (vpiHandle obj_h = vpi_scan(instItr)) {
        std::function<std::string(vpiHandle, std::string)> inst_visit =
            [&inst_visit](vpiHandle obj_h, std::string path) {
              std::string res;
              std::string objectName;
              if (const char* s = vpi_get_str(vpiName, obj_h)) {
                objectName = s;
              }
              if (objectName.size()) {
                res += path + objectName + "\n";
                path += objectName + ".";
              }
              // Recursive tree traversal
              vpiHandle subItr = vpi_iterate(vpiModule, obj_h);
              while (vpiHandle sub_h = vpi_scan(subItr)) {
                res += inst_visit(sub_h, path);
                vpi_release_handle(sub_h);
              }
              vpi_release_handle(subItr);
              subItr = vpi_iterate(vpiGenScopeArray, obj_h);
              while (vpiHandle sub_h = vpi_scan(subItr)) {
                res += inst_visit(sub_h, path);
                vpi_release_handle(sub_h);
              }
              vpi_release_handle(subItr);
              subItr = vpi_iterate(vpiGenScope, obj_h);
              while (vpiHandle sub_h = vpi_scan(subItr)) {
                res += inst_visit(sub_h, path);
                vpi_release_handle(sub_h);
              }
              vpi_release_handle(subItr);
              return res;
            };
        result += inst_visit(obj_h, "");
        vpi_release_handle(obj_h);
      }
      vpi_release_handle(instItr);
    }
  }
  std::cout << result;
  return 0;
};
<commit_msg>legalize traversal<commit_after>/*
 * Copyright 2021 Alain Dargelas
 *
 * 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 <errno.h>
#include <limits.h> /* PATH_MAX */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>

#include <algorithm>
#include <fstream>
#include <iostream>
#include <regex>
#include <sstream>
#include <string>

#if !(defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__))
#include <dirent.h>
#include <unistd.h>
#endif

#include "headers/uhdm.h"
#include "headers/vpi_listener.h"

using namespace UHDM;

static int usage(const char* progname) {
  fprintf(stderr, "Usage:\n%s [options] <uhdm-file>\n", progname);
  fprintf(stderr,
          "Reads UHDM binary representation and prints hierarchy tree.\n");
  return 1;
}

int main(int argc, char** argv) {
  std::string uhdmFile;

  // Simple option parsing that works on all platforms.
  for (int i = 1; i < argc; ++i) {
    const std::string arg = argv[i];
    if (uhdmFile.empty())
      uhdmFile = arg;
    else
      return usage(argv[0]);
  }

  if (uhdmFile.empty()) {
    return usage(argv[0]);
  }

  struct stat buffer;
  if (stat(uhdmFile.c_str(), &buffer) != 0) {
    std::cerr << uhdmFile << ": File does not exist!" << std::endl;
    return usage(argv[0]);
  }

  Serializer serializer;
  std::vector<vpiHandle> restoredDesigns = serializer.Restore(uhdmFile);

  if (restoredDesigns.empty()) {
    std::cerr << uhdmFile << ": empty design." << std::endl;
    return 1;
  }
  std::string result;
  for (vpiHandle design : restoredDesigns) {
    if (vpi_get(vpiType, design) == vpiDesign) {
      result +=
          "Design name: " + std::string(vpi_get_str(vpiName, design)) + "\n";
      result += "Instance tree:\n";

      vpiHandle instItr = vpi_iterate(UHDM::uhdmtopModules, design);
      while (vpiHandle obj_h = vpi_scan(instItr)) {
        std::function<std::string(vpiHandle, std::string)> inst_visit =
            [&inst_visit](vpiHandle obj_h, std::string path) {
              std::string res;
              std::string objectName;
              if (const char* s = vpi_get_str(vpiName, obj_h)) {
                objectName = s;
              }
              if (objectName.size()) {
                res += path + objectName + "\n";
                path += objectName + ".";
              }
              // Recursive tree traversal
	      if (vpi_get(vpiType, obj_h) == vpiModule || vpi_get(vpiType, obj_h) == vpiGenScope) {
                vpiHandle subItr = vpi_iterate(vpiModule, obj_h);
                while (vpiHandle sub_h = vpi_scan(subItr)) {
                  res += inst_visit(sub_h, path);
		  vpi_release_handle(sub_h);
                }
	        vpi_release_handle(subItr);
	      }
	      if (vpi_get(vpiType, obj_h) == vpiModule || vpi_get(vpiType, obj_h) == vpiGenScope) {
                vpiHandle subItr = vpi_iterate(vpiGenScopeArray, obj_h);
                while (vpiHandle sub_h = vpi_scan(subItr)) {
                  res += inst_visit(sub_h, path);
	  	  vpi_release_handle(sub_h);
                }
	        vpi_release_handle(subItr);
	      }
	      if (vpi_get(vpiType, obj_h) == vpiGenScopeArray) {
                vpiHandle subItr = vpi_iterate(vpiGenScope, obj_h);
                while (vpiHandle sub_h = vpi_scan(subItr)) {
                  res += inst_visit(sub_h, path);
	  	  vpi_release_handle(sub_h);
                }
		vpi_release_handle(subItr);
	      }
              return res;
            };
        result += inst_visit(obj_h, "");
	vpi_release_handle(obj_h);
      }
      vpi_release_handle(instItr);
    }
  }
  std::cout << result;
  return 0;
};
<|endoftext|>


<commit_before>#include "argumentlist.h"
#include "epolleventdispatcher.h"
#include "localsocket.h"
#include "stringtools.h"
#include "pathfinder.h"

#include <iostream>
#include <sstream>

using namespace std;

void printArguments(ArgumentList::ReadCursor reader )
{
    // TODO - this is well-known though
}

int main(int argc, char *argv[])
{
    // TODO find session bus
    SessionBusInfo sessionBusInfo = PathFinder::sessionBusInfo();
    cout << "session bus address type: " << sessionBusInfo.addressType << '\n';
    cout << "session bus path: " << sessionBusInfo.path << '\n';

    LocalSocket sock(sessionBusInfo.path);
    cout << "connection is " << (sock.isOpen() ? "open" : "closed") << ".\n";

    int uid = 1000; // H4X
    stringstream uidDecimal;
    uidStream << uid;
    stringstream uidDecimal;
    cout << uidStream.str() << ':' << hexEncode(uidStream.str()) << '\n';

    // TODO authentication ping-pong
    // some findings:
    // - the string after the server OK is its UUID that also appears in the address string
    // - the string after the client "EXTERNAL" is the hex-encoded UID

    // only for API testing so far! make this look better with better API!
    EpollEventDispatcher dispatcher;

    sock.setEventDispatcher(&dispatcher);
#if 0
    // TODO
    LocalSocket ls(....);
    dispatcher.add(&cnx)
    while (true) {
        dispatcher.poll();
        if (!cnx.hasMessage()) {
            continue;
        }
        Message msg = cnx.takeMessage();
        ArgumentList argList = msg.argumentList();
        ArgumentList::ReadCursor reader = argList.beginRead();
        printArguments(reader);
    }
#endif
    return 0;
}
<commit_msg>Compile.<commit_after>#include "argumentlist.h"
#include "epolleventdispatcher.h"
#include "localsocket.h"
#include "stringtools.h"
#include "pathfinder.h"

#include <iostream>
#include <sstream>

using namespace std;

void printArguments(ArgumentList::ReadCursor reader )
{
    // TODO - this is well-known though
}

int main(int argc, char *argv[])
{
    // TODO find session bus
    SessionBusInfo sessionBusInfo = PathFinder::sessionBusInfo();
    cout << "session bus address type: " << sessionBusInfo.addressType << '\n';
    cout << "session bus path: " << sessionBusInfo.path << '\n';

    LocalSocket sock(sessionBusInfo.path);
    cout << "connection is " << (sock.isOpen() ? "open" : "closed") << ".\n";

    int uid = 1000; // H4X
    stringstream uidDecimal;
    uidDecimal << uid;
    cout << uidDecimal.str() << ':' << hexEncode(uidDecimal.str()) << '\n';

    // TODO authentication ping-pong
    // some findings:
    // - the string after the server OK is its UUID that also appears in the address string
    // - the string after the client "EXTERNAL" is the hex-encoded UID

    // only for API testing so far! make this look better with better API!
    EpollEventDispatcher dispatcher;

    sock.setEventDispatcher(&dispatcher);
#if 0
    // TODO
    LocalSocket ls(....);
    dispatcher.add(&cnx)
    while (true) {
        dispatcher.poll();
        if (!cnx.hasMessage()) {
            continue;
        }
        Message msg = cnx.takeMessage();
        ArgumentList argList = msg.argumentList();
        ArgumentList::ReadCursor reader = argList.beginRead();
        printArguments(reader);
    }
#endif
    return 0;
}
<|endoftext|>


<commit_before>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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 <gmock/gmock.h>

#include <stout/gtest.hpp>
#include <stout/json.hpp>
#include <stout/os.hpp>
#include <stout/path.hpp>
#include <stout/stringify.hpp>

#include <process/future.hpp>
#include <process/gmock.hpp>
#include <process/owned.hpp>

#include <mesos/docker/spec.hpp>

#include "slave/containerizer/mesos/provisioner/docker/metadata_manager.hpp"
#include "slave/containerizer/mesos/provisioner/docker/paths.hpp"
#include "slave/containerizer/mesos/provisioner/docker/puller.hpp"
#include "slave/containerizer/mesos/provisioner/docker/registry_puller.hpp"
#include "slave/containerizer/mesos/provisioner/docker/store.hpp"

#include "tests/mesos.hpp"
#include "tests/utils.hpp"

namespace paths = mesos::internal::slave::docker::paths;
namespace slave = mesos::internal::slave;
namespace spec = ::docker::spec;

using std::string;
using std::vector;

using process::Future;
using process::Owned;
using process::Promise;

using slave::ImageInfo;

using slave::docker::Puller;
using slave::docker::RegistryPuller;
using slave::docker::Store;

namespace mesos {
namespace internal {
namespace tests {

class ProvisionerDockerLocalStoreTest : public TemporaryDirectoryTest
{
public:
  void verifyLocalDockerImage(
      const slave::Flags& flags,
      const vector<string>& layers)
  {
    // Verify contents of the image in store directory.
    const string layerPath1 = paths::getImageLayerRootfsPath(
        flags.docker_store_dir,
        "123");

    const string layerPath2 = paths::getImageLayerRootfsPath(
        flags.docker_store_dir,
        "456");

    EXPECT_TRUE(os::exists(layerPath1));
    EXPECT_TRUE(os::exists(layerPath2));

    EXPECT_SOME_EQ(
        "foo 123",
        os::read(path::join(layerPath1 , "temp")));

    EXPECT_SOME_EQ(
        "bar 456",
        os::read(path::join(layerPath2, "temp")));

    // Verify the Docker Image provided.
    vector<string> expectedLayers;
    expectedLayers.push_back(layerPath1);
    expectedLayers.push_back(layerPath2);
    EXPECT_EQ(expectedLayers, layers);
  }

protected:
  virtual void SetUp()
  {
    TemporaryDirectoryTest::SetUp();

    const string archivesDir = path::join(os::getcwd(), "images");
    const string image = path::join(archivesDir, "abc");
    ASSERT_SOME(os::mkdir(archivesDir));
    ASSERT_SOME(os::mkdir(image));

    JSON::Value repositories = JSON::parse(
        "{"
        "  \"abc\": {"
        "    \"latest\": \"456\""
        "  }"
        "}").get();
    ASSERT_SOME(
        os::write(path::join(image, "repositories"), stringify(repositories)));

    ASSERT_SOME(os::mkdir(path::join(image, "123")));
    JSON::Value manifest123 = JSON::parse(
        "{"
        "  \"parent\": \"\""
        "}").get();
    ASSERT_SOME(os::write(
        path::join(image, "123", "json"), stringify(manifest123)));
    ASSERT_SOME(os::mkdir(path::join(image, "123", "layer")));
    ASSERT_SOME(
        os::write(path::join(image, "123", "layer", "temp"), "foo 123"));

    // Must change directory to avoid carrying over /path/to/archive during tar.
    const string cwd = os::getcwd();
    ASSERT_SOME(os::chdir(path::join(image, "123", "layer")));
    ASSERT_SOME(os::tar(".", "../layer.tar"));
    ASSERT_SOME(os::chdir(cwd));
    ASSERT_SOME(os::rmdir(path::join(image, "123", "layer")));

    ASSERT_SOME(os::mkdir(path::join(image, "456")));
    JSON::Value manifest456 = JSON::parse(
        "{"
        "  \"parent\": \"123\""
        "}").get();
    ASSERT_SOME(
        os::write(path::join(image, "456", "json"), stringify(manifest456)));
    ASSERT_SOME(os::mkdir(path::join(image, "456", "layer")));
    ASSERT_SOME(
        os::write(path::join(image, "456", "layer", "temp"), "bar 456"));

    ASSERT_SOME(os::chdir(path::join(image, "456", "layer")));
    ASSERT_SOME(os::tar(".", "../layer.tar"));
    ASSERT_SOME(os::chdir(cwd));
    ASSERT_SOME(os::rmdir(path::join(image, "456", "layer")));

    ASSERT_SOME(os::chdir(image));
    ASSERT_SOME(os::tar(".", "../abc.tar"));
    ASSERT_SOME(os::chdir(cwd));
    ASSERT_SOME(os::rmdir(image));
  }
};

// This test verifies that a locally stored Docker image in the form of a
// tar achive created from a 'docker save' command can be unpacked and
// stored in the proper locations accessible to the Docker provisioner.
TEST_F(ProvisionerDockerLocalStoreTest, LocalStoreTestWithTar)
{
  const string archivesDir = path::join(os::getcwd(), "images");
  const string image = path::join(archivesDir, "abc");
  ASSERT_SOME(os::mkdir(archivesDir));
  ASSERT_SOME(os::mkdir(image));

  slave::Flags flags;
  flags.docker_registry = archivesDir;
  flags.docker_store_dir = path::join(os::getcwd(), "store");

  Try<Owned<slave::Store>> store = slave::docker::Store::create(flags);
  ASSERT_SOME(store);

  Image mesosImage;
  mesosImage.set_type(Image::DOCKER);
  mesosImage.mutable_docker()->set_name("abc");

  Future<slave::ImageInfo> imageInfo = store.get()->get(mesosImage);
  AWAIT_READY(imageInfo);

  verifyLocalDockerImage(flags, imageInfo.get().layers);
}

// This tests the ability of the metadata manger to recover the images it has
// already stored on disk when it is initialized.
TEST_F(ProvisionerDockerLocalStoreTest, MetadataManagerInitialization)
{
  slave::Flags flags;
  flags.docker_registry = path::join(os::getcwd(), "images");
  flags.docker_store_dir = path::join(os::getcwd(), "store");

  Try<Owned<slave::Store>> store = slave::docker::Store::create(flags);
  ASSERT_SOME(store);

  Image image;
  image.set_type(Image::DOCKER);
  image.mutable_docker()->set_name("abc");

  Future<slave::ImageInfo> imageInfo = store.get()->get(image);
  AWAIT_READY(imageInfo);

  // Store is deleted and recreated. Metadata Manager is initialized upon
  // creation of the store.
  store.get().reset();
  store = slave::docker::Store::create(flags);
  ASSERT_SOME(store);
  Future<Nothing> recover = store.get()->recover();
  AWAIT_READY(recover);

  imageInfo = store.get()->get(image);
  AWAIT_READY(imageInfo);
  verifyLocalDockerImage(flags, imageInfo.get().layers);
}

class MockPuller : public Puller
{
public:
  MockPuller()
  {
    EXPECT_CALL(*this, pull(_, _))
      .WillRepeatedly(Invoke(this, &MockPuller::unmocked_pull));
  }

  virtual ~MockPuller() {}

  MOCK_METHOD2(
      pull,
      Future<vector<string>>(
          const spec::ImageReference&,
          const string&));

  Future<vector<string>> unmocked_pull(
      const spec::ImageReference& reference,
      const string& directory)
  {
    // TODO(gilbert): Allow return list to be overridden.
    return vector<string>();
  }
};

// This tests the store to pull the same image simutanuously.
// This test verifies that the store only calls the puller once
// when multiple requests for the same image is in flight.
TEST_F(ProvisionerDockerLocalStoreTest, PullingSameImageSimutanuously)
{
  const string archivesDir = path::join(os::getcwd(), "images");
  const string image = path::join(archivesDir, "abc:latest");
  ASSERT_SOME(os::mkdir(archivesDir));
  ASSERT_SOME(os::mkdir(image));

  slave::Flags flags;
  flags.docker_registry = "file://" + archivesDir;
  flags.docker_store_dir = path::join(os::getcwd(), "store");

  MockPuller* puller = new MockPuller();
  Future<Nothing> pull;
  Future<string> directory;
  Promise<vector<string>> promise;

  EXPECT_CALL(*puller, pull(_, _))
    .WillOnce(testing::DoAll(FutureSatisfy(&pull),
                             FutureArg<1>(&directory),
                             Return(promise.future())));

  Try<Owned<slave::Store>> store =
      slave::docker::Store::create(flags, Owned<Puller>(puller));
  ASSERT_SOME(store);

  Image mesosImage;
  mesosImage.set_type(Image::DOCKER);
  mesosImage.mutable_docker()->set_name("abc");

  Future<slave::ImageInfo> imageInfo1 = store.get()->get(mesosImage);
  AWAIT_READY(pull);
  AWAIT_READY(directory);

  // TODO(gilbert): Need a helper method to create test layers
  // which will allow us to set manifest so that we can add
  // checks here.
  const string layerPath = path::join(directory.get(), "456");

  Try<Nothing> mkdir = os::mkdir(layerPath);
  ASSERT_SOME(mkdir);

  JSON::Value manifest = JSON::parse(
        "{"
        "  \"parent\": \"\""
        "}").get();

  ASSERT_SOME(
      os::write(path::join(layerPath, "json"), stringify(manifest)));

  ASSERT_TRUE(imageInfo1.isPending());
  Future<slave::ImageInfo> imageInfo2 = store.get()->get(mesosImage);

  const vector<string> result = {"456"};

  ASSERT_TRUE(imageInfo2.isPending());
  promise.set(result);

  AWAIT_READY(imageInfo1);
  AWAIT_READY(imageInfo2);

  EXPECT_EQ(imageInfo1.get().layers, imageInfo2.get().layers);
}

class ProvisionerDockerRegistryPullerTest : public TemporaryDirectoryTest {};

TEST_F(ProvisionerDockerRegistryPullerTest, INTERNET_CURL_Pull)
{
  slave::Flags flags;
  flags.docker_registry = "https://registry-1.docker.io";
  flags.docker_store_dir = os::getcwd();

  Try<Owned<slave::Store>> store = Store::create(flags);
  ASSERT_SOME(store);

  Image image;
  image.set_type(Image::DOCKER);
  image.mutable_docker()->set_name("library/alpine");

  Future<ImageInfo> imageInfo = store.get()->get(image);
  AWAIT_READY_FOR(imageInfo, Seconds(60));

  EXPECT_LE(1u, imageInfo->layers.size());
  EXPECT_SOME(imageInfo->dockerManifest);
}

} // namespace tests {
} // namespace internal {
} // namespace mesos {
<commit_msg>Added an end-to-end test for docker registry puller.<commit_after>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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 <gmock/gmock.h>

#include <stout/gtest.hpp>
#include <stout/json.hpp>
#include <stout/os.hpp>
#include <stout/path.hpp>
#include <stout/stringify.hpp>

#include <process/future.hpp>
#include <process/gmock.hpp>
#include <process/owned.hpp>

#include <mesos/docker/spec.hpp>

#include "slave/containerizer/mesos/provisioner/docker/metadata_manager.hpp"
#include "slave/containerizer/mesos/provisioner/docker/paths.hpp"
#include "slave/containerizer/mesos/provisioner/docker/puller.hpp"
#include "slave/containerizer/mesos/provisioner/docker/registry_puller.hpp"
#include "slave/containerizer/mesos/provisioner/docker/store.hpp"

#include "tests/mesos.hpp"
#include "tests/utils.hpp"

namespace master = mesos::internal::master;
namespace paths = mesos::internal::slave::docker::paths;
namespace slave = mesos::internal::slave;
namespace spec = ::docker::spec;

using std::string;
using std::vector;

using process::Future;
using process::Owned;
using process::PID;
using process::Promise;

using master::Master;

using slave::ImageInfo;
using slave::Slave;

using slave::docker::Puller;
using slave::docker::RegistryPuller;
using slave::docker::Store;

namespace mesos {
namespace internal {
namespace tests {

class ProvisionerDockerLocalStoreTest : public TemporaryDirectoryTest
{
public:
  void verifyLocalDockerImage(
      const slave::Flags& flags,
      const vector<string>& layers)
  {
    // Verify contents of the image in store directory.
    const string layerPath1 = paths::getImageLayerRootfsPath(
        flags.docker_store_dir,
        "123");

    const string layerPath2 = paths::getImageLayerRootfsPath(
        flags.docker_store_dir,
        "456");

    EXPECT_TRUE(os::exists(layerPath1));
    EXPECT_TRUE(os::exists(layerPath2));

    EXPECT_SOME_EQ(
        "foo 123",
        os::read(path::join(layerPath1 , "temp")));

    EXPECT_SOME_EQ(
        "bar 456",
        os::read(path::join(layerPath2, "temp")));

    // Verify the Docker Image provided.
    vector<string> expectedLayers;
    expectedLayers.push_back(layerPath1);
    expectedLayers.push_back(layerPath2);
    EXPECT_EQ(expectedLayers, layers);
  }

protected:
  virtual void SetUp()
  {
    TemporaryDirectoryTest::SetUp();

    const string archivesDir = path::join(os::getcwd(), "images");
    const string image = path::join(archivesDir, "abc");
    ASSERT_SOME(os::mkdir(archivesDir));
    ASSERT_SOME(os::mkdir(image));

    JSON::Value repositories = JSON::parse(
        "{"
        "  \"abc\": {"
        "    \"latest\": \"456\""
        "  }"
        "}").get();
    ASSERT_SOME(
        os::write(path::join(image, "repositories"), stringify(repositories)));

    ASSERT_SOME(os::mkdir(path::join(image, "123")));
    JSON::Value manifest123 = JSON::parse(
        "{"
        "  \"parent\": \"\""
        "}").get();
    ASSERT_SOME(os::write(
        path::join(image, "123", "json"), stringify(manifest123)));
    ASSERT_SOME(os::mkdir(path::join(image, "123", "layer")));
    ASSERT_SOME(
        os::write(path::join(image, "123", "layer", "temp"), "foo 123"));

    // Must change directory to avoid carrying over /path/to/archive during tar.
    const string cwd = os::getcwd();
    ASSERT_SOME(os::chdir(path::join(image, "123", "layer")));
    ASSERT_SOME(os::tar(".", "../layer.tar"));
    ASSERT_SOME(os::chdir(cwd));
    ASSERT_SOME(os::rmdir(path::join(image, "123", "layer")));

    ASSERT_SOME(os::mkdir(path::join(image, "456")));
    JSON::Value manifest456 = JSON::parse(
        "{"
        "  \"parent\": \"123\""
        "}").get();
    ASSERT_SOME(
        os::write(path::join(image, "456", "json"), stringify(manifest456)));
    ASSERT_SOME(os::mkdir(path::join(image, "456", "layer")));
    ASSERT_SOME(
        os::write(path::join(image, "456", "layer", "temp"), "bar 456"));

    ASSERT_SOME(os::chdir(path::join(image, "456", "layer")));
    ASSERT_SOME(os::tar(".", "../layer.tar"));
    ASSERT_SOME(os::chdir(cwd));
    ASSERT_SOME(os::rmdir(path::join(image, "456", "layer")));

    ASSERT_SOME(os::chdir(image));
    ASSERT_SOME(os::tar(".", "../abc.tar"));
    ASSERT_SOME(os::chdir(cwd));
    ASSERT_SOME(os::rmdir(image));
  }
};

// This test verifies that a locally stored Docker image in the form of a
// tar achive created from a 'docker save' command can be unpacked and
// stored in the proper locations accessible to the Docker provisioner.
TEST_F(ProvisionerDockerLocalStoreTest, LocalStoreTestWithTar)
{
  const string archivesDir = path::join(os::getcwd(), "images");
  const string image = path::join(archivesDir, "abc");
  ASSERT_SOME(os::mkdir(archivesDir));
  ASSERT_SOME(os::mkdir(image));

  slave::Flags flags;
  flags.docker_registry = archivesDir;
  flags.docker_store_dir = path::join(os::getcwd(), "store");

  Try<Owned<slave::Store>> store = slave::docker::Store::create(flags);
  ASSERT_SOME(store);

  Image mesosImage;
  mesosImage.set_type(Image::DOCKER);
  mesosImage.mutable_docker()->set_name("abc");

  Future<slave::ImageInfo> imageInfo = store.get()->get(mesosImage);
  AWAIT_READY(imageInfo);

  verifyLocalDockerImage(flags, imageInfo.get().layers);
}

// This tests the ability of the metadata manger to recover the images it has
// already stored on disk when it is initialized.
TEST_F(ProvisionerDockerLocalStoreTest, MetadataManagerInitialization)
{
  slave::Flags flags;
  flags.docker_registry = path::join(os::getcwd(), "images");
  flags.docker_store_dir = path::join(os::getcwd(), "store");

  Try<Owned<slave::Store>> store = slave::docker::Store::create(flags);
  ASSERT_SOME(store);

  Image image;
  image.set_type(Image::DOCKER);
  image.mutable_docker()->set_name("abc");

  Future<slave::ImageInfo> imageInfo = store.get()->get(image);
  AWAIT_READY(imageInfo);

  // Store is deleted and recreated. Metadata Manager is initialized upon
  // creation of the store.
  store.get().reset();
  store = slave::docker::Store::create(flags);
  ASSERT_SOME(store);
  Future<Nothing> recover = store.get()->recover();
  AWAIT_READY(recover);

  imageInfo = store.get()->get(image);
  AWAIT_READY(imageInfo);
  verifyLocalDockerImage(flags, imageInfo.get().layers);
}

class MockPuller : public Puller
{
public:
  MockPuller()
  {
    EXPECT_CALL(*this, pull(_, _))
      .WillRepeatedly(Invoke(this, &MockPuller::unmocked_pull));
  }

  virtual ~MockPuller() {}

  MOCK_METHOD2(
      pull,
      Future<vector<string>>(
          const spec::ImageReference&,
          const string&));

  Future<vector<string>> unmocked_pull(
      const spec::ImageReference& reference,
      const string& directory)
  {
    // TODO(gilbert): Allow return list to be overridden.
    return vector<string>();
  }
};

// This tests the store to pull the same image simutanuously.
// This test verifies that the store only calls the puller once
// when multiple requests for the same image is in flight.
TEST_F(ProvisionerDockerLocalStoreTest, PullingSameImageSimutanuously)
{
  const string archivesDir = path::join(os::getcwd(), "images");
  const string image = path::join(archivesDir, "abc:latest");
  ASSERT_SOME(os::mkdir(archivesDir));
  ASSERT_SOME(os::mkdir(image));

  slave::Flags flags;
  flags.docker_registry = "file://" + archivesDir;
  flags.docker_store_dir = path::join(os::getcwd(), "store");

  MockPuller* puller = new MockPuller();
  Future<Nothing> pull;
  Future<string> directory;
  Promise<vector<string>> promise;

  EXPECT_CALL(*puller, pull(_, _))
    .WillOnce(testing::DoAll(FutureSatisfy(&pull),
                             FutureArg<1>(&directory),
                             Return(promise.future())));

  Try<Owned<slave::Store>> store =
      slave::docker::Store::create(flags, Owned<Puller>(puller));
  ASSERT_SOME(store);

  Image mesosImage;
  mesosImage.set_type(Image::DOCKER);
  mesosImage.mutable_docker()->set_name("abc");

  Future<slave::ImageInfo> imageInfo1 = store.get()->get(mesosImage);
  AWAIT_READY(pull);
  AWAIT_READY(directory);

  // TODO(gilbert): Need a helper method to create test layers
  // which will allow us to set manifest so that we can add
  // checks here.
  const string layerPath = path::join(directory.get(), "456");

  Try<Nothing> mkdir = os::mkdir(layerPath);
  ASSERT_SOME(mkdir);

  JSON::Value manifest = JSON::parse(
        "{"
        "  \"parent\": \"\""
        "}").get();

  ASSERT_SOME(
      os::write(path::join(layerPath, "json"), stringify(manifest)));

  ASSERT_TRUE(imageInfo1.isPending());
  Future<slave::ImageInfo> imageInfo2 = store.get()->get(mesosImage);

  const vector<string> result = {"456"};

  ASSERT_TRUE(imageInfo2.isPending());
  promise.set(result);

  AWAIT_READY(imageInfo1);
  AWAIT_READY(imageInfo2);

  EXPECT_EQ(imageInfo1.get().layers, imageInfo2.get().layers);
}

#ifdef __linux__
class ProvisionerDockerRegistryPullerTest : public MesosTest {};

// TODO(jieyu): This is a ROOT test because of MESOS-4757. Remove the
// ROOT restriction after MESOS-4757 is resolved.
TEST_F(ProvisionerDockerRegistryPullerTest, ROOT_INTERNET_CURL_ShellCommand)
{
  Try<PID<Master>> master = StartMaster();
  ASSERT_SOME(master);

  slave::Flags flags = CreateSlaveFlags();
  flags.isolation = "docker/runtime,filesystem/linux";
  flags.image_providers = "docker";
  flags.docker_registry = "https://registry-1.docker.io";

  Try<PID<Slave>> slave = StartSlave(flags);
  ASSERT_SOME(slave);

  MockScheduler sched;
  MesosSchedulerDriver driver(
      &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL);

  EXPECT_CALL(sched, registered(&driver, _, _));

  Future<vector<Offer>> offers;
  EXPECT_CALL(sched, resourceOffers(&driver, _))
    .WillOnce(FutureArg<1>(&offers))
    .WillRepeatedly(Return()); // Ignore subsequent offers.

  driver.start();

  AWAIT_READY(offers);
  ASSERT_EQ(1u, offers->size());

  const Offer& offer = offers.get()[0];

  TaskInfo task = createTask(
      offer.slave_id(),
      Resources::parse("cpus:1;mem:128").get(),
      "ls -al /");

  Image image;
  image.set_type(Image::DOCKER);
  image.mutable_docker()->set_name("library/alpine");

  ContainerInfo* container = task.mutable_container();
  container->set_type(ContainerInfo::MESOS);
  container->mutable_mesos()->mutable_image()->CopyFrom(image);

  Future<TaskStatus> statusRunning;
  Future<TaskStatus> statusFinished;
  EXPECT_CALL(sched, statusUpdate(&driver, _))
    .WillOnce(FutureArg<1>(&statusRunning))
    .WillOnce(FutureArg<1>(&statusFinished));

  driver.launchTasks(offer.id(), {task});

  AWAIT_READY_FOR(statusRunning, Seconds(60));
  EXPECT_EQ(task.task_id(), statusRunning->task_id());
  EXPECT_EQ(TASK_RUNNING, statusRunning->state());

  AWAIT_READY(statusFinished);
  EXPECT_EQ(task.task_id(), statusFinished->task_id());
  EXPECT_EQ(TASK_FINISHED, statusFinished->state());

  driver.stop();
  driver.join();

  Shutdown();
}
#endif

} // namespace tests {
} // namespace internal {
} // namespace mesos {
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2012 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 "compilation_unit.h"

#include "compiled_method.h"
#include "instruction_set.h"
#include "ir_builder.h"
#include "logging.h"

#include "runtime_support_builder_arm.h"
#include "runtime_support_builder_x86.h"

#include <llvm/ADT/OwningPtr.h>
#include <llvm/ADT/StringSet.h>
#include <llvm/ADT/Triple.h>
#include <llvm/Analysis/CallGraph.h>
#include <llvm/Analysis/DebugInfo.h>
#include <llvm/Analysis/LoopPass.h>
#include <llvm/Analysis/RegionPass.h>
#include <llvm/Analysis/Verifier.h>
#include <llvm/Assembly/PrintModulePass.h>
#include <llvm/Bitcode/ReaderWriter.h>
#include <llvm/CallGraphSCCPass.h>
#include <llvm/CodeGen/MachineFrameInfo.h>
#include <llvm/CodeGen/MachineFunction.h>
#include <llvm/CodeGen/MachineFunctionPass.h>
#include <llvm/DerivedTypes.h>
#include <llvm/LLVMContext.h>
#include <llvm/Module.h>
#include <llvm/PassManager.h>
#include <llvm/Support/Debug.h>
#include <llvm/Support/FormattedStream.h>
#include <llvm/Support/ManagedStatic.h>
#include <llvm/Support/PassNameParser.h>
#include <llvm/Support/PluginLoader.h>
#include <llvm/Support/PrettyStackTrace.h>
#include <llvm/Support/Signals.h>
#include <llvm/Support/SystemUtils.h>
#include <llvm/Support/TargetRegistry.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/ToolOutputFile.h>
#include <llvm/Support/raw_ostream.h>
#include <llvm/Target/TargetData.h>
#include <llvm/Target/TargetLibraryInfo.h>
#include <llvm/Target/TargetMachine.h>
#include <llvm/Transforms/IPO/PassManagerBuilder.h>

#include <string>

namespace {

class UpdateFrameSizePass : public llvm::MachineFunctionPass {
 public:
  static char ID;

  UpdateFrameSizePass() : llvm::MachineFunctionPass(ID), cunit_(NULL) {
    LOG(FATAL) << "Unexpected instantiation of UpdateFrameSizePass";
    // NOTE: We have to declare this constructor for llvm::RegisterPass, but
    // this constructor won't work because we have no information on
    // CompilationUnit.  Thus, we should place a LOG(FATAL) here.
  }

  UpdateFrameSizePass(art::compiler_llvm::CompilationUnit* cunit)
    : llvm::MachineFunctionPass(ID), cunit_(cunit) {
  }

  virtual bool runOnMachineFunction(llvm::MachineFunction &MF) {
    cunit_->UpdateFrameSizeInBytes(MF.getFunction(),
                                   MF.getFrameInfo()->getStackSize());
    return false;
  }

 private:
  art::compiler_llvm::CompilationUnit* cunit_;
};

char UpdateFrameSizePass::ID = 0;

llvm::RegisterPass<UpdateFrameSizePass> reg_update_frame_size_pass_(
  "update-frame-size", "Update frame size pass", false, false);

} // end anonymous namespace

namespace art {
namespace compiler_llvm {

llvm::Module* makeLLVMModuleContents(llvm::Module* module);

CompilationUnit::CompilationUnit(InstructionSet insn_set, size_t elf_idx)
: insn_set_(insn_set), elf_idx_(elf_idx), context_(new llvm::LLVMContext()),
  mem_usage_(0), num_elf_funcs_(0) {

  // Create the module and include the runtime function declaration
  module_ = new llvm::Module("art", *context_);
  makeLLVMModuleContents(module_);

  // Create IRBuilder
  irb_.reset(new IRBuilder(*context_, *module_));

  // We always need a switch case, so just use a normal function.
  switch(insn_set_) {
    default:
      runtime_support_.reset(new RuntimeSupportBuilder(*context_, *module_, *irb_));
      break;
  case kArm:
  case kThumb2:
    runtime_support_.reset(new RuntimeSupportBuilderARM(*context_, *module_, *irb_));
    break;
  case kX86:
    runtime_support_.reset(new RuntimeSupportBuilderX86(*context_, *module_, *irb_));
    break;
  }

  runtime_support_->OptimizeRuntimeSupport();

  irb_->SetRuntimeSupport(runtime_support_.get());
}

CompilationUnit::~CompilationUnit() {
}

bool CompilationUnit::WriteBitcodeToFile() {
  std::string errmsg;

  llvm::OwningPtr<llvm::tool_output_file> out_file(
    new llvm::tool_output_file(bitcode_filename_.c_str(), errmsg,
                               llvm::raw_fd_ostream::F_Binary));

  if (!errmsg.empty()) {
    LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
    return false;
  }

  llvm::WriteBitcodeToFile(module_, out_file->os());
  out_file->keep();

  return true;
}

bool CompilationUnit::Materialize() {
  // Lookup the LLVM target
  char const* target_triple = NULL;
  char const* target_attr = NULL;

  switch (insn_set_) {
  case kThumb2:
    target_triple = "thumb-none-linux-gnueabi";
    target_attr = "+thumb2,+neon,+neonfp,+vfp3";
    break;

  case kArm:
    target_triple = "armv7-none-linux-gnueabi";
    target_attr = "+v7,+neon,+neonfp,+vfp3";
    break;

  case kX86:
    target_triple = "i386-pc-linux-gnu";
    target_attr = "";
    break;

  case kMips:
    target_triple = "mipsel-unknown-linux";
    target_attr = "mips32r2";
    break;

  default:
    LOG(FATAL) << "Unknown instruction set: " << insn_set_;
  }

  std::string errmsg;
  llvm::Target const* target =
    llvm::TargetRegistry::lookupTarget(target_triple, errmsg);

  CHECK(target != NULL) << errmsg;

  // Target options
  llvm::TargetOptions target_options;
  target_options.FloatABIType = llvm::FloatABI::Soft;
  target_options.NoFramePointerElim = true;
  target_options.NoFramePointerElimNonLeaf = true;
  target_options.UseSoftFloat = false;

  // Create the llvm::TargetMachine
  llvm::TargetMachine* target_machine =
    target->createTargetMachine(target_triple, "", target_attr, target_options,
                                llvm::Reloc::Static, llvm::CodeModel::Small,
                                llvm::CodeGenOpt::Aggressive);

  CHECK(target_machine != NULL) << "Failed to create target machine";

  // Add target data
  llvm::TargetData const* target_data = target_machine->getTargetData();

  // PassManager for code generation passes
  llvm::PassManager pm;
  pm.add(new llvm::TargetData(*target_data));

  // FunctionPassManager for optimization pass
  llvm::FunctionPassManager fpm(module_);
  fpm.add(new llvm::TargetData(*target_data));

  // Add optimization pass
  llvm::PassManagerBuilder pm_builder;
  pm_builder.Inliner = NULL; // TODO: add some inline in the future
  pm_builder.OptLevel = 3;
  pm_builder.DisableSimplifyLibCalls = 1;
  pm_builder.populateModulePassManager(pm);
  pm_builder.populateFunctionPassManager(fpm);

  // Add passes to emit ELF image
  {
    llvm::formatted_raw_ostream formatted_os(
      *(new llvm::raw_string_ostream(elf_image_)), true);

    // Ask the target to add backend passes as necessary.
    if (target_machine->addPassesToEmitFile(pm,
                                            formatted_os,
                                            llvm::TargetMachine::CGFT_ObjectFile,
                                            true)) {
      LOG(FATAL) << "Unable to generate ELF for this target";
      return false;
    }

    // Add pass to update the frame_size_in_bytes_
    pm.add(new ::UpdateFrameSizePass(this));

    // Run the per-function optimization
    fpm.doInitialization();
    for (llvm::Module::iterator F = module_->begin(), E = module_->end();
         F != E; ++F) {
      fpm.run(*F);
    }
    fpm.doFinalization();

    // Run the code generation passes
    pm.run(*module_);
  }

  LOG(INFO) << "Compilation Unit: " << elf_idx_ << " (done)";

  // Free the resources
  context_.reset(NULL);
  irb_.reset(NULL);
  module_ = NULL;

  return true;
}

void CompilationUnit::RegisterCompiledMethod(const llvm::Function* func,
                                             CompiledMethod* compiled_method) {
  compiled_methods_map_.Put(func, compiled_method);
}

void CompilationUnit::UpdateFrameSizeInBytes(const llvm::Function* func,
                                             size_t frame_size_in_bytes) {
  SafeMap<const llvm::Function*, CompiledMethod*>::iterator iter =
    compiled_methods_map_.find(func);

  if (iter != compiled_methods_map_.end()) {
    CompiledMethod* compiled_method = iter->second;
    compiled_method->SetFrameSizeInBytes(frame_size_in_bytes);

    if (frame_size_in_bytes > 1728u) {
      LOG(WARNING) << "Huge frame size: " << frame_size_in_bytes
                   << " elf_idx=" << compiled_method->GetElfIndex()
                   << " elf_func_idx=" << compiled_method->GetElfFuncIndex();
    }
  }
}

} // namespace compiler_llvm
} // namespace art
<commit_msg>am 54a3e919: Compilation_unit experiment.<commit_after>/*
 * Copyright (C) 2012 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 "compilation_unit.h"

#include "compiled_method.h"
#include "instruction_set.h"
#include "ir_builder.h"
#include "logging.h"

#include "runtime_support_builder_arm.h"
#include "runtime_support_builder_x86.h"

#include <llvm/ADT/OwningPtr.h>
#include <llvm/ADT/StringSet.h>
#include <llvm/ADT/Triple.h>
#include <llvm/Analysis/CallGraph.h>
#include <llvm/Analysis/DebugInfo.h>
#include <llvm/Analysis/LoopPass.h>
#include <llvm/Analysis/RegionPass.h>
#include <llvm/Analysis/Verifier.h>
#include <llvm/Assembly/PrintModulePass.h>
#include <llvm/Bitcode/ReaderWriter.h>
#include <llvm/CallGraphSCCPass.h>
#include <llvm/CodeGen/MachineFrameInfo.h>
#include <llvm/CodeGen/MachineFunction.h>
#include <llvm/CodeGen/MachineFunctionPass.h>
#include <llvm/DerivedTypes.h>
#include <llvm/LLVMContext.h>
#include <llvm/Module.h>
#include <llvm/PassManager.h>
#include <llvm/Support/Debug.h>
#include <llvm/Support/FormattedStream.h>
#include <llvm/Support/ManagedStatic.h>
#include <llvm/Support/PassNameParser.h>
#include <llvm/Support/PluginLoader.h>
#include <llvm/Support/PrettyStackTrace.h>
#include <llvm/Support/Signals.h>
#include <llvm/Support/SystemUtils.h>
#include <llvm/Support/TargetRegistry.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/ToolOutputFile.h>
#include <llvm/Support/raw_ostream.h>
#include <llvm/Target/TargetData.h>
#include <llvm/Target/TargetLibraryInfo.h>
#include <llvm/Target/TargetMachine.h>
#include <llvm/Transforms/IPO/PassManagerBuilder.h>

#include <string>

namespace {

class UpdateFrameSizePass : public llvm::MachineFunctionPass {
 public:
  static char ID;

  UpdateFrameSizePass() : llvm::MachineFunctionPass(ID), cunit_(NULL) {
    LOG(FATAL) << "Unexpected instantiation of UpdateFrameSizePass";
    // NOTE: We have to declare this constructor for llvm::RegisterPass, but
    // this constructor won't work because we have no information on
    // CompilationUnit.  Thus, we should place a LOG(FATAL) here.
  }

  UpdateFrameSizePass(art::compiler_llvm::CompilationUnit* cunit)
    : llvm::MachineFunctionPass(ID), cunit_(cunit) {
  }

  virtual bool runOnMachineFunction(llvm::MachineFunction &MF) {
    cunit_->UpdateFrameSizeInBytes(MF.getFunction(),
                                   MF.getFrameInfo()->getStackSize());
    return false;
  }

 private:
  art::compiler_llvm::CompilationUnit* cunit_;
};

char UpdateFrameSizePass::ID = 0;

llvm::RegisterPass<UpdateFrameSizePass> reg_update_frame_size_pass_(
  "update-frame-size", "Update frame size pass", false, false);

} // end anonymous namespace

namespace art {
namespace compiler_llvm {

llvm::Module* makeLLVMModuleContents(llvm::Module* module);

CompilationUnit::CompilationUnit(InstructionSet insn_set, size_t elf_idx)
: insn_set_(insn_set), elf_idx_(elf_idx), context_(new llvm::LLVMContext()),
  mem_usage_(0), num_elf_funcs_(0) {

  // Create the module and include the runtime function declaration
  module_ = new llvm::Module("art", *context_);
  makeLLVMModuleContents(module_);

  // Create IRBuilder
  irb_.reset(new IRBuilder(*context_, *module_));

  // We always need a switch case, so just use a normal function.
  switch(insn_set_) {
    default:
      runtime_support_.reset(new RuntimeSupportBuilder(*context_, *module_, *irb_));
      break;
  case kArm:
  case kThumb2:
    runtime_support_.reset(new RuntimeSupportBuilderARM(*context_, *module_, *irb_));
    break;
  case kX86:
    runtime_support_.reset(new RuntimeSupportBuilderX86(*context_, *module_, *irb_));
    break;
  }

  runtime_support_->OptimizeRuntimeSupport();

  irb_->SetRuntimeSupport(runtime_support_.get());
}

CompilationUnit::~CompilationUnit() {
}

bool CompilationUnit::WriteBitcodeToFile() {
  std::string errmsg;

  llvm::OwningPtr<llvm::tool_output_file> out_file(
    new llvm::tool_output_file(bitcode_filename_.c_str(), errmsg,
                               llvm::raw_fd_ostream::F_Binary));

  if (!errmsg.empty()) {
    LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
    return false;
  }

  llvm::WriteBitcodeToFile(module_, out_file->os());
  out_file->keep();

  return true;
}

bool CompilationUnit::Materialize() {
  // Lookup the LLVM target
  char const* target_triple = NULL;
  char const* target_attr = NULL;

  switch (insn_set_) {
  case kThumb2:
    target_triple = "thumb-none-linux-gnueabi";
    target_attr = "+thumb2,+neon,+neonfp,+vfp3";
    break;

  case kArm:
    target_triple = "armv7-none-linux-gnueabi";
    target_attr = "+v7,+neon,+neonfp,+vfp3";
    break;

  case kX86:
    target_triple = "i386-pc-linux-gnu";
    target_attr = "";
    break;

  case kMips:
    target_triple = "mipsel-unknown-linux";
    target_attr = "mips32r2";
    break;

  default:
    LOG(FATAL) << "Unknown instruction set: " << insn_set_;
  }

  std::string errmsg;
  llvm::Target const* target =
    llvm::TargetRegistry::lookupTarget(target_triple, errmsg);

  CHECK(target != NULL) << errmsg;

  // Target options
  llvm::TargetOptions target_options;
  target_options.FloatABIType = llvm::FloatABI::Soft;
  target_options.NoFramePointerElim = true;
  target_options.NoFramePointerElimNonLeaf = true;
  target_options.UseSoftFloat = false;

  // Create the llvm::TargetMachine
  llvm::TargetMachine* target_machine =
    target->createTargetMachine(target_triple, "", target_attr, target_options,
                                llvm::Reloc::Static, llvm::CodeModel::Small,
                                llvm::CodeGenOpt::None);

  CHECK(target_machine != NULL) << "Failed to create target machine";

  // Add target data
  llvm::TargetData const* target_data = target_machine->getTargetData();

  // PassManager for code generation passes
  llvm::PassManager pm;
  pm.add(new llvm::TargetData(*target_data));

  // FunctionPassManager for optimization pass
  llvm::FunctionPassManager fpm(module_);
  fpm.add(new llvm::TargetData(*target_data));

  // Add passes to emit ELF image
  {
    llvm::formatted_raw_ostream formatted_os(
      *(new llvm::raw_string_ostream(elf_image_)), true);

    // Ask the target to add backend passes as necessary.
    if (target_machine->addPassesToEmitFile(pm,
                                            formatted_os,
                                            llvm::TargetMachine::CGFT_ObjectFile,
                                            true)) {
      LOG(FATAL) << "Unable to generate ELF for this target";
      return false;
    }

    // Add pass to update the frame_size_in_bytes_
    pm.add(new ::UpdateFrameSizePass(this));

    // Run the code generation passes
    pm.run(*module_);
  }

  LOG(INFO) << "Compilation Unit: " << elf_idx_ << " (done)";

  // Free the resources
  context_.reset(NULL);
  irb_.reset(NULL);
  module_ = NULL;

  return true;
}

void CompilationUnit::RegisterCompiledMethod(const llvm::Function* func,
                                             CompiledMethod* compiled_method) {
  compiled_methods_map_.Put(func, compiled_method);
}

void CompilationUnit::UpdateFrameSizeInBytes(const llvm::Function* func,
                                             size_t frame_size_in_bytes) {
  SafeMap<const llvm::Function*, CompiledMethod*>::iterator iter =
    compiled_methods_map_.find(func);

  if (iter != compiled_methods_map_.end()) {
    CompiledMethod* compiled_method = iter->second;
    compiled_method->SetFrameSizeInBytes(frame_size_in_bytes);

    if (frame_size_in_bytes > 1728u) {
      LOG(WARNING) << "Huge frame size: " << frame_size_in_bytes
                   << " elf_idx=" << compiled_method->GetElfIndex()
                   << " elf_func_idx=" << compiled_method->GetElfFuncIndex();
    }
  }
}

} // namespace compiler_llvm
} // namespace art
<|endoftext|>