<commit_before>///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) DreamWorks Animation LLC
//
// All rights reserved. This software is distributed under the
// Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
//
// Redistributions of source code must retain the above copyright
// and license notice and the following restrictions and disclaimer.
//
// *     Neither the name of DreamWorks Animation nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
// LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
//
///////////////////////////////////////////////////////////////////////////

/// @file TempFile.cc

#include "TempFile.h"

#include <openvdb/Exceptions.h>
#ifndef _MSC_VER
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/version.hpp> // for BOOST_VERSION
#include <cstdlib> // for std::getenv(), mkstemp()
#include <sys/types.h> // for mode_t
#include <sys/stat.h> // for mkdir(), umask()
#include <unistd.h> // for access()
#else
#include <fstream> // for std::filebuf
#endif
#include <cstdio> // for std::tmpnam(), L_tmpnam, P_tmpdir
#include <iostream>
#include <sstream>
#include <string>
#include <vector>

#ifndef DWA_BOOST_VERSION
#define DWA_BOOST_VERSION (10 * BOOST_VERSION)
#endif

namespace openvdb {
OPENVDB_USE_VERSION_NAMESPACE
namespace OPENVDB_VERSION_NAME {
namespace io {

struct TempFile::TempFileImpl
{
    const std::string& filename() const { return mPath; }

    bool is_open() const { return mBuffer.is_open(); }

    /// @internal boost::filesystem::unique_path(), etc. might be useful here,
    /// but as of 9/2014, Houdini ships without the Boost.Filesystem library,
    /// which makes it much less convenient to use that library.
#ifndef _MSC_VER
    TempFileImpl(std::ostream& os): mFileDescr(-1) { this->init(os); }

    void init(std::ostream& os)
    {
        std::string fn = this->getTempDir() + "/openvdb_temp_XXXXXX";
        std::vector<char> fnbuf(fn.begin(), fn.end());
        fnbuf.push_back(char(0));

        //const mode_t savedMode = ::umask(~(S_IRUSR | S_IWUSR));
        mFileDescr = ::mkstemp(&fnbuf[0]);
        //::umask(savedMode);
        if (mFileDescr < 0) {
            OPENVDB_THROW(IoError, "failed to generate temporary file");
        }

        mPath.assign(&fnbuf[0]);

#if DWA_BOOST_VERSION >= 1046000
        mDevice = DeviceType(mFileDescr, boost::iostreams::never_close_handle);
#else
        mDevice = DeviceType(mFileDescr, /*closeOnExit=*/false);
#endif
        mBuffer.open(mDevice);
        os.rdbuf(&mBuffer);

        if (!os.good()) {
            OPENVDB_THROW(IoError, "failed to open temporary file " + mPath);
        }
    }

    void close() { mBuffer.close(); if (mFileDescr >= 0) ::close(mFileDescr); }

    static std::string getTempDir()
    {
        if (const char* dir = std::getenv("OPENVDB_TEMP_DIR")) {
            if (0 != ::access(dir, F_OK)) {
                ::mkdir(dir, S_IRUSR | S_IWUSR | S_IXUSR);
                if (0 != ::access(dir, F_OK)) {
                    OPENVDB_THROW(IoError,
                        "failed to create OPENVDB_TEMP_DIR (" + std::string(dir) + ")");
                }
            }
            return dir;
        }
        if (const char* dir = std::getenv("TMPDIR")) return dir;
        return P_tmpdir;
    }

    using DeviceType = boost::iostreams::file_descriptor_sink;
    using BufferType = boost::iostreams::stream_buffer<boost::iostreams::file_descriptor_sink>;

    std::string mPath;
    DeviceType mDevice;
    BufferType mBuffer;
    int mFileDescr;
#else // _MSC_VER
    // Use only standard library routines; no POSIX.

    TempFileImpl(std::ostream& os) { this->init(os); }

    void init(std::ostream& os)
    {
        char fnbuf[L_tmpnam];
        const char* filename = std::tmpnam(fnbuf);
        if (!filename) {
            OPENVDB_THROW(IoError, "failed to generate name for temporary file");
        }
        /// @todo This is not safe, since another process could open a file
        /// with this name before we do.  Unfortunately, there is no safe,
        /// portable way to create a temporary file.
        mPath = filename;

        const std::ios_base::openmode mode = (std::ios_base::out | std::ios_base::binary);
        os.rdbuf(mBuffer.open(mPath.c_str(), mode));
        if (!os.good()) {
            OPENVDB_THROW(IoError, "failed to open temporary file " + mPath);
        }
    }

    void close() { mBuffer.close(); }

    std::string mPath;
    std::filebuf mBuffer;
#endif // _MSC_VER

private:
    TempFileImpl(const TempFileImpl&); // disable copying
    TempFileImpl& operator=(const TempFileImpl&); // disable assignment
};

TempFile::TempFile(): std::ostream(nullptr), mImpl(new TempFileImpl(*this)) {}
TempFile::~TempFile() { this->close(); }
const std::string& TempFile::filename() const { return mImpl->filename(); }
bool TempFile::is_open() const { return mImpl->is_open(); }
void TempFile::close() { mImpl->close(); }

} // namespace io
} // namespace OPENVDB_VERSION_NAME
} // namespace openvdb

// Copyright (c) DreamWorks Animation LLC
// All rights reserved. This software is distributed under the
// Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
<commit_msg>Remove logic supporting Boost 1.46<commit_after>///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) DreamWorks Animation LLC
//
// All rights reserved. This software is distributed under the
// Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
//
// Redistributions of source code must retain the above copyright
// and license notice and the following restrictions and disclaimer.
//
// *     Neither the name of DreamWorks Animation nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
// LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
//
///////////////////////////////////////////////////////////////////////////

/// @file TempFile.cc

#include "TempFile.h"

#include <openvdb/Exceptions.h>
#ifndef _MSC_VER
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/device/file_descriptor.hpp>
#include <cstdlib> // for std::getenv(), mkstemp()
#include <sys/types.h> // for mode_t
#include <sys/stat.h> // for mkdir(), umask()
#include <unistd.h> // for access()
#else
#include <fstream> // for std::filebuf
#endif
#include <cstdio> // for std::tmpnam(), L_tmpnam, P_tmpdir
#include <iostream>
#include <sstream>
#include <string>
#include <vector>

namespace openvdb {
OPENVDB_USE_VERSION_NAMESPACE
namespace OPENVDB_VERSION_NAME {
namespace io {

struct TempFile::TempFileImpl
{
    const std::string& filename() const { return mPath; }

    bool is_open() const { return mBuffer.is_open(); }

    /// @internal boost::filesystem::unique_path(), etc. might be useful here,
    /// but as of 9/2014, Houdini ships without the Boost.Filesystem library,
    /// which makes it much less convenient to use that library.
#ifndef _MSC_VER
    TempFileImpl(std::ostream& os): mFileDescr(-1) { this->init(os); }

    void init(std::ostream& os)
    {
        std::string fn = this->getTempDir() + "/openvdb_temp_XXXXXX";
        std::vector<char> fnbuf(fn.begin(), fn.end());
        fnbuf.push_back(char(0));

        //const mode_t savedMode = ::umask(~(S_IRUSR | S_IWUSR));
        mFileDescr = ::mkstemp(&fnbuf[0]);
        //::umask(savedMode);
        if (mFileDescr < 0) {
            OPENVDB_THROW(IoError, "failed to generate temporary file");
        }

        mPath.assign(&fnbuf[0]);

        mDevice = DeviceType(mFileDescr, boost::iostreams::never_close_handle);
        mBuffer.open(mDevice);
        os.rdbuf(&mBuffer);

        if (!os.good()) {
            OPENVDB_THROW(IoError, "failed to open temporary file " + mPath);
        }
    }

    void close() { mBuffer.close(); if (mFileDescr >= 0) ::close(mFileDescr); }

    static std::string getTempDir()
    {
        if (const char* dir = std::getenv("OPENVDB_TEMP_DIR")) {
            if (0 != ::access(dir, F_OK)) {
                ::mkdir(dir, S_IRUSR | S_IWUSR | S_IXUSR);
                if (0 != ::access(dir, F_OK)) {
                    OPENVDB_THROW(IoError,
                        "failed to create OPENVDB_TEMP_DIR (" + std::string(dir) + ")");
                }
            }
            return dir;
        }
        if (const char* dir = std::getenv("TMPDIR")) return dir;
        return P_tmpdir;
    }

    using DeviceType = boost::iostreams::file_descriptor_sink;
    using BufferType = boost::iostreams::stream_buffer<boost::iostreams::file_descriptor_sink>;

    std::string mPath;
    DeviceType mDevice;
    BufferType mBuffer;
    int mFileDescr;
#else // _MSC_VER
    // Use only standard library routines; no POSIX.

    TempFileImpl(std::ostream& os) { this->init(os); }

    void init(std::ostream& os)
    {
        char fnbuf[L_tmpnam];
        const char* filename = std::tmpnam(fnbuf);
        if (!filename) {
            OPENVDB_THROW(IoError, "failed to generate name for temporary file");
        }
        /// @todo This is not safe, since another process could open a file
        /// with this name before we do.  Unfortunately, there is no safe,
        /// portable way to create a temporary file.
        mPath = filename;

        const std::ios_base::openmode mode = (std::ios_base::out | std::ios_base::binary);
        os.rdbuf(mBuffer.open(mPath.c_str(), mode));
        if (!os.good()) {
            OPENVDB_THROW(IoError, "failed to open temporary file " + mPath);
        }
    }

    void close() { mBuffer.close(); }

    std::string mPath;
    std::filebuf mBuffer;
#endif // _MSC_VER

private:
    TempFileImpl(const TempFileImpl&); // disable copying
    TempFileImpl& operator=(const TempFileImpl&); // disable assignment
};

TempFile::TempFile(): std::ostream(nullptr), mImpl(new TempFileImpl(*this)) {}
TempFile::~TempFile() { this->close(); }
const std::string& TempFile::filename() const { return mImpl->filename(); }
bool TempFile::is_open() const { return mImpl->is_open(); }
void TempFile::close() { mImpl->close(); }

} // namespace io
} // namespace OPENVDB_VERSION_NAME
} // namespace openvdb

// Copyright (c) DreamWorks Animation LLC
// All rights reserved. This software is distributed under the
// Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
<|endoftext|>


<commit_before>//////////////////////////////////////////////////
//
// An example application which generates PYX notation.
// It's a pretty literal translation of the Sean McGrath's
// sax2pyx.py code presented in his XML Processing In Python book.
//
// For more information on PYX see http://pyxie.sourceforce.net/
//
// $Id$
//
//////////////////////////////////////////////////

#ifdef _MSC_VER
#pragma warning(disable : 4786)
#endif

#include <SAX/helpers/DefaultHandler.h>
#include <SAX/InputSource.h>
#include <SAX/XMLReader.h>
#include <iostream>

class SAX2PYX : public SAX::DefaultHandler
{
  public:
    virtual void startElement(const std::string& namespaceURI, const std::string& localName,
                              const std::string& qName, const SAX::Attributes& atts);
    virtual void endElement(const std::string& namespaceURI, const std::string& localName,
                            const std::string& qName);
    virtual void characters(const std::string& ch);
    virtual void processingInstruction(const std::string& target, const std::string& data);

    virtual void warning(const SAX::SAXException& e) { fatalError(e); }
    virtual void error(const SAX::SAXException& e) { fatalError(e); }
    virtual void fatalError(const SAX::SAXException& e);

  private:
    std::string escape(const std::string& str) const;
}; // class SimpleHandler

int main(int argc, char* argv[])
{
  if(argc == 1)
	{
		std::cout << "Usage : " << argv[0] << " xmlfile ... " << std::endl;
		return 0;
	} // if(argc == 0)

	SAX2PYX handler;

	for(int i = 1; i < argc; ++i)
	{
    SAX::XMLReader<std::string> myParser;
		myParser.setContentHandler(handler);
		myParser.setErrorHandler(handler);

    SAX::InputSource is(argv[i]);
    myParser.parse(is);
	}

	return 0;
} // main

void SAX2PYX::startElement(const std::string& namespaceURI, const std::string& localName,
                           const std::string& qName, const SAX::Attributes& atts)
{
  std::cout << '(' << localName << std::endl;

  for(int i = 0; i < atts.getLength(); ++i)
  {
    std::cout << 'A' << atts.getLocalName(i)
              << ' ' << escape(atts.getValue(i))
              << std::endl;
  } // for ...

} // startElement

void SAX2PYX::endElement(const std::string& namespaceURI, const std::string& localName,
                       const std::string& qName)
{
  std::cout << ')' << localName << std::endl;
} // endElement

void SAX2PYX::characters(const std::string& ch)
{
  std::cout << '-' << escape(ch) << std::endl;
} // characters

void SAX2PYX::processingInstruction(const std::string& target, const std::string& data)
{
  std::cout << '?' << target
            << ' ' << data << std::endl;
} // processingInstruction

std::string SAX2PYX::escape(const std::string& str) const
{
  std::string estr(str);
  std::string::size_type i(estr.find("\n"));
  while(i != std::string::npos)
  {
    estr.replace(i, 1, "\\n", 2);
    i = estr.find("\n", i);
  } // while ...
  return estr;
} // escape

void SAX2PYX::fatalError(const SAX::SAXException& e)
{
  std::cerr << "Parse problem " << e.what() << std::endl;
  exit(0);
} // fatalError

// end of file
<commit_msg>Used DefaultHandler::fatalError and catch thrown exception<commit_after>//////////////////////////////////////////////////
//
// An example application which generates PYX notation.
// It's a pretty literal translation of the Sean McGrath's
// sax2pyx.py code presented in his XML Processing In Python book.
//
// For more information on PYX see http://pyxie.sourceforce.net/
//
// $Id$
//
//////////////////////////////////////////////////

#ifdef _MSC_VER
#pragma warning(disable : 4786)
#endif

#include <SAX/helpers/DefaultHandler.h>
#include <SAX/InputSource.h>
#include <SAX/XMLReader.h>
#include <iostream>

class SAX2PYX : public SAX::DefaultHandler
{
  public:
    virtual void startElement(const std::string& namespaceURI, const std::string& localName,
                              const std::string& qName, const SAX::Attributes& atts);
    virtual void endElement(const std::string& namespaceURI, const std::string& localName,
                            const std::string& qName);
    virtual void characters(const std::string& ch);
    virtual void processingInstruction(const std::string& target, const std::string& data);

    virtual void warning(const SAX::SAXParseException& e) { fatalError(e); }
    virtual void error(const SAX::SAXParseException& e) { fatalError(e); }

  private:
    std::string escape(const std::string& str) const;
}; // class SimpleHandler

int main(int argc, char* argv[])
{
  if(argc == 1)
	{
		std::cout << "Usage : " << argv[0] << " xmlfile ... " << std::endl;
		return 0;
	} // if(argc == 0)

	SAX2PYX handler;

	for(int i = 1; i < argc; ++i)
	{
    try
    {
      SAX::XMLReader<std::string> myParser;
		  myParser.setContentHandler(handler);
		  myParser.setErrorHandler(handler);

      SAX::InputSource is(argv[i]);
      myParser.parse(is);
    } // try
    catch(std::runtime_error& e)
    {
      std::cerr << "Parse problem " << e.what() << std::endl;
    } // catch
	} // for ...

	return 0;
} // main

void SAX2PYX::startElement(const std::string&, const std::string& localName,
                           const std::string&, const SAX::Attributes& atts)
{
  std::cout << '(' << localName << std::endl;

  for(int i = 0; i < atts.getLength(); ++i)
  {
    std::cout << 'A' << atts.getLocalName(i)
              << ' ' << escape(atts.getValue(i))
              << std::endl;
  } // for ...

} // startElement

void SAX2PYX::endElement(const std::string&, const std::string& localName,
                       const std::string&)
{
  std::cout << ')' << localName << std::endl;
} // endElement

void SAX2PYX::characters(const std::string& ch)
{
  std::cout << '-' << escape(ch) << std::endl;
} // characters

void SAX2PYX::processingInstruction(const std::string& target, const std::string& data)
{
  std::cout << '?' << target
            << ' ' << data << std::endl;
} // processingInstruction

std::string SAX2PYX::escape(const std::string& str) const
{
  std::string estr(str);
  std::string::size_type i(estr.find("\n"));
  while(i != std::string::npos)
  {
    estr.replace(i, 1, "\\n", 2);
    i = estr.find("\n", i);
  } // while ...
  return estr;
} // escape

// end of file
<|endoftext|>


<commit_before>#ifndef __PY2CPP_HPP__
#define __PY2CPP_HPP__

#include <Python.h>

#include <cassert>
#include <climits>
#include <sstream>
#include <stdexcept>
#include <typeinfo>

#include <map>
#include <set>
#include <string>
#include <tuple>

namespace dubzzz {
namespace Py2Cpp {

template <class T>
struct CppBuilder;

template <>
struct CppBuilder<PyObject*>
{
  PyObject* operator() (PyObject* pyo)
  {
    assert(pyo);
    return pyo;
  }
};

template <>
struct CppBuilder<bool>
{
  bool operator() (PyObject* pyo)
  {
    assert(pyo);
    if (PyBool_Check(pyo))
    {
      return pyo == Py_True;
    }
    throw std::invalid_argument("Not a PyBool instance");
  }
};

template <>
struct CppBuilder<int>
{
  int operator() (PyObject* pyo)
  {
    assert(pyo);
    if (PyLong_Check(pyo))
    {
      long v { PyLong_AsLong(pyo) };
      if (v < INT_MIN || v > INT_MAX)
      {
        throw std::overflow_error("Out of <int> boundaries");
      }
      return static_cast<int>(v);
    }
    else if (PyInt_Check(pyo))
    {
      long v { PyInt_AS_LONG(pyo) };
      if (v < INT_MIN || v > INT_MAX)
      {
        throw std::overflow_error("Out of <int> boundaries");
      }
      return static_cast<int>(v);
    }
    throw std::invalid_argument("Not a PyLong instance");
  }
};

template <>
struct CppBuilder<unsigned int>
{
  unsigned int operator() (PyObject* pyo)
  {
    assert(pyo);
    if (PyLong_Check(pyo))
    {
      unsigned long v { PyLong_AsUnsignedLongMask(pyo) };
      if (v > UINT_MAX)
      {
        throw std::overflow_error("Out of <unsigned int> boundaries");
      }
      return static_cast<unsigned int>(v);
    }
    else if (PyInt_Check(pyo))
    {
      unsigned long v { PyInt_AsUnsignedLongMask(pyo) };
      if (v > UINT_MAX)
      {
        throw std::overflow_error("Out of <unsigned int> boundaries");
      }
      return static_cast<int>(v);
    }
    throw std::invalid_argument("Not a PyLong instance");
  }
};

template <>
struct CppBuilder<long>
{
  long operator() (PyObject* pyo)
  {
    assert(pyo);
    if (PyLong_Check(pyo))
    {
      long value { PyLong_AsLong(pyo) };
      if (!! PyErr_Occurred() && !! PyErr_ExceptionMatches(PyExc_OverflowError))
      {
        PyErr_Clear();
        throw std::overflow_error("Out of <long> boundaries");
      }
      return value;
    }
    else if (PyInt_Check(pyo))
    {
      return PyInt_AS_LONG(pyo);
    }
    throw std::invalid_argument("Not a PyLong instance");
  }
};

template <>
struct CppBuilder<unsigned long>
{
  unsigned long operator() (PyObject* pyo)
  {
    assert(pyo);
    if (PyLong_Check(pyo))
    {
      unsigned long value { PyLong_AsUnsignedLong(pyo) };
      if (!! PyErr_Occurred() && !! PyErr_ExceptionMatches(PyExc_OverflowError))
      {
        PyErr_Clear();
        throw std::overflow_error("Out of <unsigned long> boundaries");
      }
      return value;
    }
    else if (PyInt_Check(pyo))
    {
      long value { PyInt_AsLong(pyo) }; // PyInt is a long, LONG_MAX < ULONG_MAX
      if (value < 0)
      {
        throw std::overflow_error("Out of <unsigned long> boundaries");
      }
      return static_cast<unsigned long>(value);
    }
    throw std::invalid_argument("Not a PyLong instance");
  }
};

template <>
struct CppBuilder<long long>
{
  long long operator() (PyObject* pyo)
  {
    assert(pyo);
    if (PyLong_Check(pyo))
    {
      return PyLong_AsLongLong(pyo);
    }
    else if (PyInt_Check(pyo))
    {
      return PyInt_AS_LONG(pyo);
    }
    throw std::invalid_argument("Not a PyLong instance");
  }
};

template <>
struct CppBuilder<unsigned long long>
{
  unsigned long long operator() (PyObject* pyo)
  {
    assert(pyo);
    if (PyLong_Check(pyo))
    {
      return PyLong_AsUnsignedLongLong(pyo);
    }
    else if (PyInt_Check(pyo))
    {
      return PyInt_AsUnsignedLongLongMask(pyo);
    }
    throw std::invalid_argument("Not a PyLong instance");
  }
};

template <>
struct CppBuilder<double>
{
  double operator() (PyObject* pyo)
  {
    assert(pyo);
    if (PyFloat_Check(pyo))
    {
      return PyFloat_AS_DOUBLE(pyo);
    }
    else if (PyLong_Check(pyo))
    {
      return PyLong_AsDouble(pyo);
    }
    else if (PyInt_Check(pyo))
    {
      return PyInt_AS_LONG(pyo);
    }
    throw std::invalid_argument("Neither a PyDouble nor a PyLong instance");
  }
};

template <>
struct CppBuilder<std::string>
{
  std::string operator() (PyObject* pyo)
  {
    assert(pyo);
    if (PyString_Check(pyo))
    {
      long int size { PyString_Size(pyo) };
      if (size < 0)
      {
        throw std::runtime_error("Unable to retrieve C/C++ string from PyString");
      }
      return std::string(PyString_AsString(pyo), size);
    }
    else if (PyUnicode_Check(pyo))
    {
      long int size { PyUnicode_GetSize(pyo) };
      if (size < 0)
      {
        throw std::runtime_error("Unable to retrieve C/C++ string from PyUnicode");
      }
      wchar_t wstr[size];
      PyUnicode_AsWideChar(reinterpret_cast<PyUnicodeObject*>(pyo), wstr, size);
      std::wstring wide(wstr, size);
      return std::string(wide.begin(), wide.end());
    }
    throw std::invalid_argument("Neither a PyString nor a PyUnicode instance");
  }
};

template <>
struct CppBuilder<std::wstring>
{
  std::wstring operator() (PyObject* pyo)
  {
    assert(pyo);
    if (PyString_Check(pyo))
    {
      const char* str { PyString_AsString(pyo) };
      long int size { PyString_Size(pyo) };
      if (size < 0)
      {
        throw std::runtime_error("Unable to retrieve C/C++ string from PyString");
      }
      wchar_t wstr[size];
      mbstowcs(wstr, str, size);
      return std::wstring(wstr, size);
    }
    else if (PyUnicode_Check(pyo))
    {
      long int size { PyUnicode_GetSize(pyo) };
      if (size < 0)
      {
        throw std::runtime_error("Unable to retrieve C/C++ string from PyUnicode");
      }
      wchar_t wstr[size];
      PyUnicode_AsWideChar(reinterpret_cast<PyUnicodeObject*>(pyo), wstr, size);
      return std::wstring(wstr, size);
    }
    throw std::invalid_argument("Neither a PyString nor a PyUnicode instance");
  }
};

template <class TUPLE, std::size_t pos>
void _feedCppTuple(TUPLE& tuple, PyObject* root)
{}

template <class TUPLE, std::size_t pos, class T, class... Args>
void _feedCppTuple(TUPLE& tuple, PyObject* root)
{

  std::get<pos>(tuple) = CppBuilder<T>()(PyTuple_GetItem(root, pos));
  _feedCppTuple<TUPLE, pos +1, Args...>(tuple, root);
}

template <class... Args>
struct CppBuilder<std::tuple<Args...>>
{
  std::tuple<Args...> operator() (PyObject* pyo)
  {
    assert(pyo);
    if (PyTuple_Check(pyo))
    {
      if (PyTuple_Size(pyo) == sizeof...(Args))
      {
        std::tuple<Args...> tuple { std::make_tuple(Args()...) };
        _feedCppTuple<std::tuple<Args...>, 0, Args...>(tuple, pyo);
        return tuple;
      }
      else
      {
        std::ostringstream oss;
        oss << "PyTuple length differs from asked one: "
            << "PyTuple(" << PyTuple_Size(pyo) << ") "
            << "and std::tuple<...>(" << sizeof...(Args) << ")";
        throw std::length_error(oss.str());
      }
    }
    throw std::invalid_argument("Not a PyTuple instance");
  }
};

/**
 * VECTOR has to have the following characteristics:
 *
 * (constructor):
 *    VECTOR(size_type count)
 *    build a VECTOR of size count
 *
 * ::begin()
 * ::end()
 * ::iterator compatible with ++it
 */
template <class VECTOR>
struct CppBuilder
{
  VECTOR operator() (PyObject* pyo)
  {
    assert(pyo);
    if (PyList_Check(pyo))
    {
      unsigned int i { 0 };
      VECTOR v(PyList_Size(pyo));
      for (typename VECTOR::iterator it { v.begin() } ; it != v.end() ; ++it, ++i)
      {
        *it = CppBuilder<typename VECTOR::value_type>()(PyList_GetItem(pyo, i));
      }
      return v;
    }
    throw std::invalid_argument("Not a PyList instance");
  }
};

template <class T>
struct CppBuilder<std::set<T>>
{
  std::set<T> operator() (PyObject* pyo)
  {
    assert(pyo);
    if (PySet_Check(pyo))
    {
      long size { PySet_Size(pyo) };
      std::vector<PyObject*> backup(size);
      std::set<T> s;
      for (long i { 0 } ; i != size ; ++i)
      {
        PyObject* popped { PySet_Pop(pyo) };
        backup[i] = popped;
        s.insert(CppBuilder<T>()(popped));
      }
      for (PyObject* popped : backup)
      {
        PySet_Add(pyo, popped);
        Py_DECREF(popped);
      }
      return s;
    }
    throw std::invalid_argument("Not a PySet instance");
  }
};

template <class K, class T>
struct CppBuilder<std::map<K,T>>
{
  std::map<K,T> operator() (PyObject* pyo)
  {
    assert(pyo);
    if (PyDict_Check(pyo))
    {
      std::map<K,T> dict;
      PyObject *key, *value;
      Py_ssize_t pos = 0;
      while (PyDict_Next(pyo, &pos, &key, &value))
      {
        dict[CppBuilder<K>()(key)] = CppBuilder<T>()(value);
      }
      return dict;
    }
    throw std::invalid_argument("Not a PyDict instance");
  }
};

}
}

#endif

<commit_msg>Fix conversions issues from PyLong to <int> and <unsigned int><commit_after>#ifndef __PY2CPP_HPP__
#define __PY2CPP_HPP__

#include <Python.h>

#include <cassert>
#include <climits>
#include <sstream>
#include <stdexcept>
#include <typeinfo>

#include <map>
#include <set>
#include <string>
#include <tuple>

namespace dubzzz {
namespace Py2Cpp {

template <class T>
struct CppBuilder;

template <>
struct CppBuilder<PyObject*>
{
  PyObject* operator() (PyObject* pyo)
  {
    assert(pyo);
    return pyo;
  }
};

template <>
struct CppBuilder<bool>
{
  bool operator() (PyObject* pyo)
  {
    assert(pyo);
    if (PyBool_Check(pyo))
    {
      return pyo == Py_True;
    }
    throw std::invalid_argument("Not a PyBool instance");
  }
};

template <>
struct CppBuilder<int>
{
  int operator() (PyObject* pyo)
  {
    assert(pyo);
    if (PyLong_Check(pyo))
    {
      long v { PyLong_AsLong(pyo) };
      if (v < INT_MIN || v > INT_MAX)
      {
        throw std::overflow_error("Out of <int> boundaries");
      }
      return static_cast<int>(v);
    }
    else if (PyInt_Check(pyo))
    {
      long v { PyInt_AS_LONG(pyo) };
      if (v < INT_MIN || v > INT_MAX)
      {
        throw std::overflow_error("Out of <int> boundaries");
      }
      return static_cast<int>(v);
    }
    throw std::invalid_argument("Not a PyLong instance");
  }
};

template <>
struct CppBuilder<unsigned int>
{
  unsigned int operator() (PyObject* pyo)
  {
    assert(pyo);
    if (PyLong_Check(pyo))
    {
      unsigned long v { PyLong_AsUnsignedLong(pyo) };
      if (!! PyErr_Occurred() && !! PyErr_ExceptionMatches(PyExc_OverflowError))
      {
        PyErr_Clear();
        throw std::overflow_error("Out of <unsigned int> boundaries");
      }
      if (v > UINT_MAX)
      {
        throw std::overflow_error("Out of <unsigned int> boundaries");
      }
      return static_cast<unsigned int>(v);
    }
    else if (PyInt_Check(pyo))
    {
      long v { PyInt_AsLong(pyo) }; // PyInt is a long, LONG_MAX < ULONG_MAX
      if (v < 0 || v > UINT_MAX)
      {
        throw std::overflow_error("Out of <unsigned int> boundaries");
      }
      return static_cast<unsigned int>(v);
    }
    throw std::invalid_argument("Not a PyLong instance");
  }
};

template <>
struct CppBuilder<long>
{
  long operator() (PyObject* pyo)
  {
    assert(pyo);
    if (PyLong_Check(pyo))
    {
      long value { PyLong_AsLong(pyo) };
      if (!! PyErr_Occurred() && !! PyErr_ExceptionMatches(PyExc_OverflowError))
      {
        PyErr_Clear();
        throw std::overflow_error("Out of <long> boundaries");
      }
      return value;
    }
    else if (PyInt_Check(pyo))
    {
      return PyInt_AS_LONG(pyo);
    }
    throw std::invalid_argument("Not a PyLong instance");
  }
};

template <>
struct CppBuilder<unsigned long>
{
  unsigned long operator() (PyObject* pyo)
  {
    assert(pyo);
    if (PyLong_Check(pyo))
    {
      unsigned long value { PyLong_AsUnsignedLong(pyo) };
      if (!! PyErr_Occurred() && !! PyErr_ExceptionMatches(PyExc_OverflowError))
      {
        PyErr_Clear();
        throw std::overflow_error("Out of <unsigned long> boundaries");
      }
      return value;
    }
    else if (PyInt_Check(pyo))
    {
      long value { PyInt_AsLong(pyo) }; // PyInt is a long, LONG_MAX < ULONG_MAX
      if (value < 0)
      {
        throw std::overflow_error("Out of <unsigned long> boundaries");
      }
      return static_cast<unsigned long>(value);
    }
    throw std::invalid_argument("Not a PyLong instance");
  }
};

template <>
struct CppBuilder<long long>
{
  long long operator() (PyObject* pyo)
  {
    assert(pyo);
    if (PyLong_Check(pyo))
    {
      return PyLong_AsLongLong(pyo);
    }
    else if (PyInt_Check(pyo))
    {
      return PyInt_AS_LONG(pyo);
    }
    throw std::invalid_argument("Not a PyLong instance");
  }
};

template <>
struct CppBuilder<unsigned long long>
{
  unsigned long long operator() (PyObject* pyo)
  {
    assert(pyo);
    if (PyLong_Check(pyo))
    {
      return PyLong_AsUnsignedLongLong(pyo);
    }
    else if (PyInt_Check(pyo))
    {
      return PyInt_AsUnsignedLongLongMask(pyo);
    }
    throw std::invalid_argument("Not a PyLong instance");
  }
};

template <>
struct CppBuilder<double>
{
  double operator() (PyObject* pyo)
  {
    assert(pyo);
    if (PyFloat_Check(pyo))
    {
      return PyFloat_AS_DOUBLE(pyo);
    }
    else if (PyLong_Check(pyo))
    {
      return PyLong_AsDouble(pyo);
    }
    else if (PyInt_Check(pyo))
    {
      return PyInt_AS_LONG(pyo);
    }
    throw std::invalid_argument("Neither a PyDouble nor a PyLong instance");
  }
};

template <>
struct CppBuilder<std::string>
{
  std::string operator() (PyObject* pyo)
  {
    assert(pyo);
    if (PyString_Check(pyo))
    {
      long int size { PyString_Size(pyo) };
      if (size < 0)
      {
        throw std::runtime_error("Unable to retrieve C/C++ string from PyString");
      }
      return std::string(PyString_AsString(pyo), size);
    }
    else if (PyUnicode_Check(pyo))
    {
      long int size { PyUnicode_GetSize(pyo) };
      if (size < 0)
      {
        throw std::runtime_error("Unable to retrieve C/C++ string from PyUnicode");
      }
      wchar_t wstr[size];
      PyUnicode_AsWideChar(reinterpret_cast<PyUnicodeObject*>(pyo), wstr, size);
      std::wstring wide(wstr, size);
      return std::string(wide.begin(), wide.end());
    }
    throw std::invalid_argument("Neither a PyString nor a PyUnicode instance");
  }
};

template <>
struct CppBuilder<std::wstring>
{
  std::wstring operator() (PyObject* pyo)
  {
    assert(pyo);
    if (PyString_Check(pyo))
    {
      const char* str { PyString_AsString(pyo) };
      long int size { PyString_Size(pyo) };
      if (size < 0)
      {
        throw std::runtime_error("Unable to retrieve C/C++ string from PyString");
      }
      wchar_t wstr[size];
      mbstowcs(wstr, str, size);
      return std::wstring(wstr, size);
    }
    else if (PyUnicode_Check(pyo))
    {
      long int size { PyUnicode_GetSize(pyo) };
      if (size < 0)
      {
        throw std::runtime_error("Unable to retrieve C/C++ string from PyUnicode");
      }
      wchar_t wstr[size];
      PyUnicode_AsWideChar(reinterpret_cast<PyUnicodeObject*>(pyo), wstr, size);
      return std::wstring(wstr, size);
    }
    throw std::invalid_argument("Neither a PyString nor a PyUnicode instance");
  }
};

template <class TUPLE, std::size_t pos>
void _feedCppTuple(TUPLE& tuple, PyObject* root)
{}

template <class TUPLE, std::size_t pos, class T, class... Args>
void _feedCppTuple(TUPLE& tuple, PyObject* root)
{

  std::get<pos>(tuple) = CppBuilder<T>()(PyTuple_GetItem(root, pos));
  _feedCppTuple<TUPLE, pos +1, Args...>(tuple, root);
}

template <class... Args>
struct CppBuilder<std::tuple<Args...>>
{
  std::tuple<Args...> operator() (PyObject* pyo)
  {
    assert(pyo);
    if (PyTuple_Check(pyo))
    {
      if (PyTuple_Size(pyo) == sizeof...(Args))
      {
        std::tuple<Args...> tuple { std::make_tuple(Args()...) };
        _feedCppTuple<std::tuple<Args...>, 0, Args...>(tuple, pyo);
        return tuple;
      }
      else
      {
        std::ostringstream oss;
        oss << "PyTuple length differs from asked one: "
            << "PyTuple(" << PyTuple_Size(pyo) << ") "
            << "and std::tuple<...>(" << sizeof...(Args) << ")";
        throw std::length_error(oss.str());
      }
    }
    throw std::invalid_argument("Not a PyTuple instance");
  }
};

/**
 * VECTOR has to have the following characteristics:
 *
 * (constructor):
 *    VECTOR(size_type count)
 *    build a VECTOR of size count
 *
 * ::begin()
 * ::end()
 * ::iterator compatible with ++it
 */
template <class VECTOR>
struct CppBuilder
{
  VECTOR operator() (PyObject* pyo)
  {
    assert(pyo);
    if (PyList_Check(pyo))
    {
      unsigned int i { 0 };
      VECTOR v(PyList_Size(pyo));
      for (typename VECTOR::iterator it { v.begin() } ; it != v.end() ; ++it, ++i)
      {
        *it = CppBuilder<typename VECTOR::value_type>()(PyList_GetItem(pyo, i));
      }
      return v;
    }
    throw std::invalid_argument("Not a PyList instance");
  }
};

template <class T>
struct CppBuilder<std::set<T>>
{
  std::set<T> operator() (PyObject* pyo)
  {
    assert(pyo);
    if (PySet_Check(pyo))
    {
      long size { PySet_Size(pyo) };
      std::vector<PyObject*> backup(size);
      std::set<T> s;
      for (long i { 0 } ; i != size ; ++i)
      {
        PyObject* popped { PySet_Pop(pyo) };
        backup[i] = popped;
        s.insert(CppBuilder<T>()(popped));
      }
      for (PyObject* popped : backup)
      {
        PySet_Add(pyo, popped);
        Py_DECREF(popped);
      }
      return s;
    }
    throw std::invalid_argument("Not a PySet instance");
  }
};

template <class K, class T>
struct CppBuilder<std::map<K,T>>
{
  std::map<K,T> operator() (PyObject* pyo)
  {
    assert(pyo);
    if (PyDict_Check(pyo))
    {
      std::map<K,T> dict;
      PyObject *key, *value;
      Py_ssize_t pos = 0;
      while (PyDict_Next(pyo, &pos, &key, &value))
      {
        dict[CppBuilder<K>()(key)] = CppBuilder<T>()(value);
      }
      return dict;
    }
    throw std::invalid_argument("Not a PyDict instance");
  }
};

}
}

#endif

<|endoftext|>


<commit_before>/*
Copyright (c) 2015-2016 Advanced Micro Devices, Inc. All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Simple test for memset.
// Also serves as a template for other tests.

/* HIT_START
 * BUILD: %t %s ../../test_common.cpp
 * RUN: %t
 * //Small copy
 * RUN: %t -N 10    --memsetval 0x42
 * // Oddball size
 * RUN: %t -N 10013 --memsetval 0x5a
 * // Big copy
 * RUN: %t -N 256M  --memsetval 0xa6
 * HIT_END
 */

#include "hip/hip_runtime.h"
#include "test_common.h"

int main(int argc, char* argv[]) {
    HipTest::parseStandardArguments(argc, argv, true);

    HIPCHECK(hipSetDevice(p_gpuDevice));

    size_t Nbytes = N * sizeof(char);

    printf("N=%zu  memsetval=%2x device=%d\n", N, memsetval, p_gpuDevice);

    char* A_d;
    char* A_h;

    HIPCHECK(hipMalloc(&A_d, Nbytes));
    A_h = (char*)malloc(Nbytes);

    HIPCHECK(hipMemset(A_d, memsetval, Nbytes));

    HIPCHECK(hipMemcpy(A_h, A_d, Nbytes, hipMemcpyDeviceToHost));

    for (int i = 0; i < N; i++) {
        if (A_h[i] != memsetval) {
            failed("mismatch at index:%d computed:%02x, memsetval:%02x\n", i, (int)A_h[i],
                   (int)memsetval);
        }
    }

    passed();
}
<commit_msg>Update hipMemset test<commit_after>/*
Copyright (c) 2015-2016 Advanced Micro Devices, Inc. All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Simple test for memset.
// Also serves as a template for other tests.

/* HIT_START
 * BUILD: %t %s ../../test_common.cpp
 * RUN: %t
 * //Small copy
 * RUN: %t -N 10    --memsetval 0x42
 * // Oddball size
 * RUN: %t -N 10013 --memsetval 0x5a
 * // Big copy
 * RUN: %t -N 256M  --memsetval 0xa6
 * HIT_END
 */

#include "hip/hip_runtime.h"
#include "test_common.h"

bool testhipMemset(int memsetval,int p_gpuDevice)
{
    size_t Nbytes = N*sizeof(char);
    printf ("testhipMemset N=%zu  memsetval=%2x device=%d\n", N, memsetval, p_gpuDevice);
    char *A_d;
    char *A_h;
    bool testResult = true;

    HIPCHECK ( hipMalloc(&A_d, Nbytes) );
    A_h = (char*)malloc(Nbytes);
    HIPCHECK ( hipMemset(A_d, memsetval, Nbytes) );
    HIPCHECK ( hipMemcpy(A_h, A_d, Nbytes, hipMemcpyDeviceToHost));

    for (int i=0; i<N; i++) {
        if (A_h[i] != memsetval) {
            testResult = false;
            printf("mismatch at index:%d computed:%02x, memsetval:%02x\n", i, (int)A_h[i], (int)memsetval);
            break;
        }
    }
    hipFree(A_d);
    free(A_h);
    return testResult;
}

bool testhipMemsetAsync(int memsetval,int p_gpuDevice)
{
    size_t Nbytes = N*sizeof(int);
    printf ("testhipMemsetAsync N=%zu  memsetval=%2x device=%d\n", N, memsetval, p_gpuDevice);
    hipDeviceptr_t A_d;
    char *A_h;
    bool testResult = true;

    HIPCHECK ( hipMalloc((void**)&A_d, Nbytes) );
    A_h = (char*)malloc(Nbytes);
    hipStream_t stream;
    HIPCHECK(hipStreamCreate(&stream));
    HIPCHECK ( hipMemsetAsync(A_d, memsetval, Nbytes, stream ));
    HIPCHECK ( hipMemcpy(A_h, (void*)A_d, Nbytes, hipMemcpyDeviceToHost));

    for (int i=0; i<N; i++) {
        if (A_h[i] != memsetval) {
            testResult = false;
            printf("mismatch at index:%d computed:%02x, memsetval:%02x\n", i, (int)A_h[i], (int)memsetval);
            break;
        }
    }
    hipFree((void*)A_d);
    free(A_h);
    return testResult;
}

int main(int argc, char *argv[])
{
    HipTest::parseStandardArguments(argc, argv, true);
    bool testResult = false;
    HIPCHECK(hipSetDevice(p_gpuDevice));
    testResult = testhipMemset(memsetval, p_gpuDevice);
    if(testResult)
        testResult = testhipMemsetAsync(memsetval, p_gpuDevice);
    if(testResult)
        passed();
}
<|endoftext|>


<commit_before>/*****************************************************************************
 * Copyright © 2014-2015 Sergey Radionov <rsatom_gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#include "qtconf.h"

#include <sstream>
#include <iomanip>

#include <boost/algorithm/string/replace.hpp>

#include <QCoreApplication>
#include <QtPlugin>
#include <QtEndian>

#include <utf8_tools.h>
#include <stdint.h>

#ifdef QT_STATIC
    #if defined( XP_WIN )
        Q_IMPORT_PLUGIN( QWindowsIntegrationPlugin );
    #elif defined( XP_MACOSX )
        Q_IMPORT_PLUGIN( QCocoaIntegrationPlugin );
    #endif
    Q_IMPORT_PLUGIN( QtQuick2Plugin );
    Q_IMPORT_PLUGIN( QtQuickLayoutsPlugin );
#endif

static std::string qtConf_resource_data;

static const unsigned char qtConf_resource_name[] = {
    // qt
    0x0,0x2,
    0x0,0x0,0x7,0x84,
    0x0,0x71,
    0x0,0x74,
    // etc
    0x0,0x3,
    0x0,0x0,0x6c,0xa3,
    0x0,0x65,
    0x0,0x74,0x0,0x63,
    // qt.conf
    0x0,0x7,
    0x8,0x74,0xa6,0xa6,
    0x0,0x71,
    0x0,0x74,0x0,0x2e,0x0,0x63,0x0,0x6f,0x0,0x6e,0x0,0x66,
};

static const unsigned char qtConf_resource_struct[] = {
    // :
    0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x1,
    // :/qt
    0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x2,
    // :/qt/etc
    0x0,0x0,0x0,0xa,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x3,
    // :/qt/etc/qt.conf
    0x0,0x0,0x0,0x16,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,
};

QT_BEGIN_NAMESPACE
extern Q_CORE_EXPORT
bool qRegisterResourceData( int, const unsigned char*,
                            const unsigned char* ,
                            const unsigned char* );
extern Q_CORE_EXPORT
bool qUnregisterResourceData( int, const unsigned char*,
                              const unsigned char*,
                              const unsigned char* );
QT_END_NAMESPACE

void InitQtConf( const std::string& prefix )
{
    Q_ASSERT( !qApp );
    if( !qApp ) {
        std::wstring qtPrefix =
            FB::utf8_to_wstring( prefix );
        boost::algorithm::replace_all( qtPrefix, L"\\", L"/" );

        std::stringstream escPrefixStream;
        for( wchar_t c : qtPrefix ) {
            if( c > 0xff )
                escPrefixStream << "\\x" << std::setfill( '0' ) << std::setw( 4 ) << std::hex << c;
            else
                escPrefixStream << static_cast<std::string::value_type>( c );;
        }

        qtConf_resource_data = "4321[Paths]\n";
        qtConf_resource_data += "Prefix = " + escPrefixStream.str() + "\n";
        uint32_t qtConfSize = qtConf_resource_data.size() - sizeof( qtConfSize );
        uint32_t qtConfSwappedSize = qToBigEndian( qtConfSize );
        memcpy( &qtConf_resource_data[0], &qtConfSwappedSize, sizeof( qtConfSwappedSize ) );

        qRegisterResourceData( 0x01, qtConf_resource_struct,
                               qtConf_resource_name,
                               (const unsigned char*)qtConf_resource_data.data() );
    }
}
<commit_msg>it's more correct to use #include <cstdint> in C++<commit_after>/*****************************************************************************
 * Copyright © 2014-2015 Sergey Radionov <rsatom_gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#include "qtconf.h"

#include <cstdint>
#include <sstream>
#include <iomanip>

#include <boost/algorithm/string/replace.hpp>

#include <QCoreApplication>
#include <QtPlugin>
#include <QtEndian>

#include <utf8_tools.h>

#ifdef QT_STATIC
    #if defined( XP_WIN )
        Q_IMPORT_PLUGIN( QWindowsIntegrationPlugin );
    #elif defined( XP_MACOSX )
        Q_IMPORT_PLUGIN( QCocoaIntegrationPlugin );
    #endif
    Q_IMPORT_PLUGIN( QtQuick2Plugin );
    Q_IMPORT_PLUGIN( QtQuickLayoutsPlugin );
#endif

static std::string qtConf_resource_data;

static const unsigned char qtConf_resource_name[] = {
    // qt
    0x0,0x2,
    0x0,0x0,0x7,0x84,
    0x0,0x71,
    0x0,0x74,
    // etc
    0x0,0x3,
    0x0,0x0,0x6c,0xa3,
    0x0,0x65,
    0x0,0x74,0x0,0x63,
    // qt.conf
    0x0,0x7,
    0x8,0x74,0xa6,0xa6,
    0x0,0x71,
    0x0,0x74,0x0,0x2e,0x0,0x63,0x0,0x6f,0x0,0x6e,0x0,0x66,
};

static const unsigned char qtConf_resource_struct[] = {
    // :
    0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x1,
    // :/qt
    0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x2,
    // :/qt/etc
    0x0,0x0,0x0,0xa,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x3,
    // :/qt/etc/qt.conf
    0x0,0x0,0x0,0x16,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,
};

QT_BEGIN_NAMESPACE
extern Q_CORE_EXPORT
bool qRegisterResourceData( int, const unsigned char*,
                            const unsigned char* ,
                            const unsigned char* );
extern Q_CORE_EXPORT
bool qUnregisterResourceData( int, const unsigned char*,
                              const unsigned char*,
                              const unsigned char* );
QT_END_NAMESPACE

void InitQtConf( const std::string& prefix )
{
    Q_ASSERT( !qApp );
    if( !qApp ) {
        std::wstring qtPrefix =
            FB::utf8_to_wstring( prefix );
        boost::algorithm::replace_all( qtPrefix, L"\\", L"/" );

        std::stringstream escPrefixStream;
        for( wchar_t c : qtPrefix ) {
            if( c > 0xff )
                escPrefixStream << "\\x" << std::setfill( '0' ) << std::setw( 4 ) << std::hex << c;
            else
                escPrefixStream << static_cast<std::string::value_type>( c );;
        }

        qtConf_resource_data = "4321[Paths]\n";
        qtConf_resource_data += "Prefix = " + escPrefixStream.str() + "\n";
        uint32_t qtConfSize = qtConf_resource_data.size() - sizeof( qtConfSize );
        uint32_t qtConfSwappedSize = qToBigEndian( qtConfSize );
        memcpy( &qtConf_resource_data[0], &qtConfSwappedSize, sizeof( qtConfSwappedSize ) );

        qRegisterResourceData( 0x01, qtConf_resource_struct,
                               qtConf_resource_name,
                               (const unsigned char*)qtConf_resource_data.data() );
    }
}
<|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/memory/memcpy.h"

#include <cstring>  // for memcpy

#include "paddle/platform/device_context.h"

namespace paddle {
namespace memory {

template <>
void Copy<platform::CPUPlace, platform::CPUPlace>(platform::CPUPlace, void* dst,
                                                  platform::CPUPlace,
                                                  const void* src, size_t num) {
  std::memcpy(dst, src, num);
}

#ifndef PADDLE_ONLY_CPU
template <>
void Copy<platform::CPUPlace, platform::GPUPlace>(platform::CPUPlace dst_place,
                                                  void* dst,
                                                  platform::GPUPlace src_place,
                                                  const void* src, size_t num,
                                                  cudaStream_t stream) {
  platform::SetDeviceId(src_place.device);
  platform::GpuMemcpyAsync(dst, src, num, cudaMemcpyDeviceToHost, stream);
}

template <>
void Copy<platform::GPUPlace, platform::CPUPlace>(platform::GPUPlace dst_place,
                                                  void* dst,
                                                  platform::CPUPlace src_place,
                                                  const void* src, size_t num,
                                                  cudaStream_t stream) {
  platform::SetDeviceId(dst_place.device);
  platform::GpuMemcpyAsync(dst, src, num, cudaMemcpyHostToDevice, stream);
}

template <>
void Copy<platform::GPUPlace, platform::GPUPlace>(platform::GPUPlace dst_place,
                                                  void* dst,
                                                  platform::GPUPlace src_place,
                                                  const void* src, size_t num,
                                                  cudaStream_t stream) {
  if (dst_place == src_place) {
    platform::SetDeviceId(src_place.device);
    platform::GpuMemcpyAsync(dst, src, num, cudaMemcpyDeviceToDevice, stream);
  } else {
    platform::GpuMemcpyPeer(dst, dst_place.device, src, src_place.device, num,
                            stream);
  }
}

#endif  // PADDLE_ONLY_CPU

}  // namespace memory
}  // namespace paddle
<commit_msg>remove device_context deps in memcpy<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/memory/memcpy.h"

#include <cstring>  // for memcpy

namespace paddle {
namespace memory {

template <>
void Copy<platform::CPUPlace, platform::CPUPlace>(platform::CPUPlace, void* dst,
                                                  platform::CPUPlace,
                                                  const void* src, size_t num) {
  std::memcpy(dst, src, num);
}

#ifndef PADDLE_ONLY_CPU
template <>
void Copy<platform::CPUPlace, platform::GPUPlace>(platform::CPUPlace dst_place,
                                                  void* dst,
                                                  platform::GPUPlace src_place,
                                                  const void* src, size_t num,
                                                  cudaStream_t stream) {
  platform::SetDeviceId(src_place.device);
  platform::GpuMemcpyAsync(dst, src, num, cudaMemcpyDeviceToHost, stream);
}

template <>
void Copy<platform::GPUPlace, platform::CPUPlace>(platform::GPUPlace dst_place,
                                                  void* dst,
                                                  platform::CPUPlace src_place,
                                                  const void* src, size_t num,
                                                  cudaStream_t stream) {
  platform::SetDeviceId(dst_place.device);
  platform::GpuMemcpyAsync(dst, src, num, cudaMemcpyHostToDevice, stream);
}

template <>
void Copy<platform::GPUPlace, platform::GPUPlace>(platform::GPUPlace dst_place,
                                                  void* dst,
                                                  platform::GPUPlace src_place,
                                                  const void* src, size_t num,
                                                  cudaStream_t stream) {
  if (dst_place == src_place) {
    platform::SetDeviceId(src_place.device);
    platform::GpuMemcpyAsync(dst, src, num, cudaMemcpyDeviceToDevice, stream);
  } else {
    platform::GpuMemcpyPeer(dst, dst_place.device, src, src_place.device, num,
                            stream);
  }
}

#endif  // PADDLE_ONLY_CPU

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


<commit_before>/*
 * PRNG for session ids.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "random.hxx"
#include "system/urandom.hxx"

#include <daemon/log.h>

#include <random>

typedef std::mt19937 Prng;
static Prng prng;

template<typename T>
static size_t
obtain_entropy(T *dest, size_t max)
{
    size_t nbytes = UrandomRead(dest, max * sizeof(dest[0]));
    return nbytes / sizeof(dest[0]);
}

void
random_seed()
{
    uint32_t seed[Prng::state_size];
    auto n = obtain_entropy(seed, Prng::state_size);
    if (n == 0)
        return;

    std::seed_seq ss(seed, seed + n);
    prng.seed(ss);
}

uint32_t
random_uint32()
{
    return prng();
}
<commit_msg>random: include cleanup<commit_after>/*
 * PRNG for session ids.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "random.hxx"
#include "system/urandom.hxx"

#include <random>

typedef std::mt19937 Prng;
static Prng prng;

template<typename T>
static size_t
obtain_entropy(T *dest, size_t max)
{
    size_t nbytes = UrandomRead(dest, max * sizeof(dest[0]));
    return nbytes / sizeof(dest[0]);
}

void
random_seed()
{
    uint32_t seed[Prng::state_size];
    auto n = obtain_entropy(seed, Prng::state_size);
    if (n == 0)
        return;

    std::seed_seq ss(seed, seed + n);
    prng.seed(ss);
}

uint32_t
random_uint32()
{
    return prng();
}
<|endoftext|>


<commit_before>#include "common/RhoPort.h"
extern "C" void Init_System();
extern "C" void Init_Network();
extern "C" void Init_SQLite3();
extern "C" void Init_Log();
extern "C" void Init_WebView();
extern "C" void Init_WebView_extension();
extern "C" void Init_Application();
extern "C" void Init_NativeToolbar();
extern "C" void Init_NativeToolbar_extension();
extern "C" void Init_NativeTabbar();
extern "C" void Init_NativeTabbar_extension();
extern "C" void Init_Navbar();
extern "C" void Init_Notification();
extern "C" void Init_RhoFile();
extern "C" void Init_NativeMenuBar();
extern "C" void Init_Led();

extern "C" void Init_CoreAPI_Extension()
{
    Init_System();
    Init_Application();

	Init_Network();
    Init_SQLite3();
    Init_Log();
#if defined(OS_MACOSX) || defined(OS_WINDOWS_DESKTOP) || defined(OS_WINCE) || defined(OS_ANDROID)
    Init_WebView();
#elif defined(OS_WP8)
    Init_WebView_extension();
#endif

#if defined(OS_WINDOWS_DESKTOP) || defined(OS_WINCE) || (defined(OS_MACOSX) && defined(RHODES_EMULATOR)) || defined(OS_ANDROID) || defined(OS_MACOSX)
    Init_NativeToolbar();
    Init_NativeTabbar();
#elif defined(OS_WP8)
    Init_NativeToolbar_extension();
    Init_NativeTabbar_extension();
#endif

#if (defined(OS_MACOSX) && !defined(RHODES_EMULATOR))
    Init_Navbar();
#endif

#if defined(OS_WINDOWS_DESKTOP) && !(defined(OS_MACOSX) && defined(RHODES_EMULATOR))
    Init_Notification();
#endif

#if defined(OS_MACOSX) || defined(OS_ANDROID) || defined(WINDOWS_PLATFORM)
    Init_RhoFile();
#endif

#if defined(OS_WINDOWS_DESKTOP) || defined(OS_WINCE)
    Init_NativeMenuBar();
#endif

#if defined(APP_BUILD_CAPABILITY_MOTOROLA)
	Init_Led();
#endif
}
<commit_msg>Fixing build issue<commit_after>#include "common/RhoPort.h"
extern "C" void Init_System();
extern "C" void Init_Network();
extern "C" void Init_SQLite3();
extern "C" void Init_Log();
extern "C" void Init_WebView();
extern "C" void Init_WebView_extension();
extern "C" void Init_Application();
extern "C" void Init_NativeToolbar();
extern "C" void Init_NativeToolbar_extension();
extern "C" void Init_NativeTabbar();
extern "C" void Init_NativeTabbar_extension();
extern "C" void Init_Navbar();
extern "C" void Init_Notification();
extern "C" void Init_RhoFile();
extern "C" void Init_NativeMenuBar();
extern "C" void Init_Led();

extern "C" void Init_CoreAPI_Extension()
{
    Init_System();
    Init_Application();

	Init_Network();
    Init_SQLite3();
    Init_Log();
#if defined(OS_MACOSX) || defined(OS_WINDOWS_DESKTOP) || defined(OS_WINCE) || defined(OS_ANDROID)
    Init_WebView();
#elif defined(OS_WP8)
    Init_WebView_extension();
#endif

#if defined(OS_WINDOWS_DESKTOP) || defined(OS_WINCE) || (defined(OS_MACOSX) && defined(RHODES_EMULATOR)) || defined(OS_ANDROID) || defined(OS_MACOSX)
    Init_NativeToolbar();
    Init_NativeTabbar();
#elif defined(OS_WP8)
    Init_NativeToolbar_extension();
    Init_NativeTabbar_extension();
#endif

#if (defined(OS_MACOSX) && !defined(RHODES_EMULATOR))
    Init_Navbar();
#endif

#if defined(OS_WINDOWS_DESKTOP) && !(defined(OS_MACOSX) && defined(RHODES_EMULATOR))
    Init_Notification();
#endif

#if defined(OS_MACOSX) || defined(OS_ANDROID) || defined(WINDOWS_PLATFORM)
    Init_RhoFile();
#endif

#if defined(OS_WINDOWS_DESKTOP) || defined(OS_WINCE)
    Init_NativeMenuBar();
#endif

#if defined(OS_WINCE)
	Init_Led();
#endif
}
<|endoftext|>


<commit_before>//===- PHITransAddr.cpp - PHI Translation for Addresses -------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the PHITransAddr class.
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/PHITransAddr.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/InstructionSimplify.h"
using namespace llvm;

static bool CanPHITrans(Instruction *Inst) {
  if (isa<PHINode>(Inst) ||
      isa<BitCastInst>(Inst) ||
      isa<GetElementPtrInst>(Inst))
    return true;

  if (Inst->getOpcode() == Instruction::And &&
      isa<ConstantInt>(Inst->getOperand(1)))
    return true;

  //   cerr << "MEMDEP: Could not PHI translate: " << *Pointer;
  //   if (isa<BitCastInst>(PtrInst) || isa<GetElementPtrInst>(PtrInst))
  //     cerr << "OP:\t\t\t\t" << *PtrInst->getOperand(0);
  return false;
}

/// IsPotentiallyPHITranslatable - If this needs PHI translation, return true
/// if we have some hope of doing it.  This should be used as a filter to
/// avoid calling PHITranslateValue in hopeless situations.
bool PHITransAddr::IsPotentiallyPHITranslatable() const {
  // If the input value is not an instruction, or if it is not defined in CurBB,
  // then we don't need to phi translate it.
  Instruction *Inst = dyn_cast<Instruction>(Addr);
  return Inst == 0 || CanPHITrans(Inst);
}

Value *PHITransAddr::PHITranslateSubExpr(Value *V, BasicBlock *CurBB,
                                         BasicBlock *PredBB) {
  // If this is a non-instruction value, it can't require PHI translation.
  Instruction *Inst = dyn_cast<Instruction>(V);
  if (Inst == 0) return V;

  // If 'Inst' is defined in this block, it must be an input that needs to be
  // phi translated or an intermediate expression that needs to be incorporated
  // into the expression.
  if (Inst->getParent() == CurBB) {
    assert(std::count(InstInputs.begin(), InstInputs.end(), Inst) &&
           "Not an input?");

    // If this is a PHI, go ahead and translate it.
    if (PHINode *PN = dyn_cast<PHINode>(Inst))
      return PN->getIncomingValueForBlock(PredBB);

    // If this is a non-phi value, and it is analyzable, we can incorporate it
    // into the expression by making all instruction operands be inputs.
    if (!CanPHITrans(Inst))
      return 0;

    // Okay, we can incorporate it, this instruction is no longer an input.
    InstInputs.erase(std::find(InstInputs.begin(), InstInputs.end(), Inst));

    // All instruction operands are now inputs (and of course, they may also be
    // defined in this block, so they may need to be phi translated themselves.
    for (unsigned i = 0, e = Inst->getNumOperands(); i != e; ++i)
      if (Instruction *Op = dyn_cast<Instruction>(Inst->getOperand(i)))
        InstInputs.push_back(Op);

  } else {
    // Determine whether 'Inst' is an input to our PHI translatable expression.
    bool isInput = std::count(InstInputs.begin(), InstInputs.end(), Inst);

    // If it is an input defined in a different block, then it remains an input.
    if (isInput)
      return Inst;
  }

  // Ok, it must be an intermediate result (either because it started that way
  // or because we just incorporated it into the expression).  See if its
  // operands need to be phi translated, and if so, reconstruct it.

  if (BitCastInst *BC = dyn_cast<BitCastInst>(Inst)) {
    Value *PHIIn = PHITranslateSubExpr(BC->getOperand(0), CurBB, PredBB);
    if (PHIIn == 0) return 0;
    if (PHIIn == BC->getOperand(0))
      return BC;

    // Find an available version of this cast.

    // Constants are trivial to find.
    if (Constant *C = dyn_cast<Constant>(PHIIn))
      return ConstantExpr::getBitCast(C, BC->getType());

    // Otherwise we have to see if a bitcasted version of the incoming pointer
    // is available.  If so, we can use it, otherwise we have to fail.
    for (Value::use_iterator UI = PHIIn->use_begin(), E = PHIIn->use_end();
         UI != E; ++UI) {
      if (BitCastInst *BCI = dyn_cast<BitCastInst>(*UI))
        if (BCI->getType() == BC->getType())
          return BCI;
    }
    return 0;
  }

  // Handle getelementptr with at least one PHI translatable operand.
  if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Inst)) {
    SmallVector<Value*, 8> GEPOps;
    BasicBlock *CurBB = GEP->getParent();
    bool AnyChanged = false;
    for (unsigned i = 0, e = GEP->getNumOperands(); i != e; ++i) {
      Value *GEPOp = PHITranslateSubExpr(GEP->getOperand(i), CurBB, PredBB);
      if (GEPOp == 0) return 0;

      AnyChanged = GEPOp != GEP->getOperand(i);
      GEPOps.push_back(GEPOp);
    }

    if (!AnyChanged)
      return GEP;

    // Simplify the GEP to handle 'gep x, 0' -> x etc.
    if (Value *V = SimplifyGEPInst(&GEPOps[0], GEPOps.size(), TD))
      return V;

    // Scan to see if we have this GEP available.
    Value *APHIOp = GEPOps[0];
    for (Value::use_iterator UI = APHIOp->use_begin(), E = APHIOp->use_end();
         UI != E; ++UI) {
      if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(*UI))
        if (GEPI->getType() == GEP->getType() &&
            GEPI->getNumOperands() == GEPOps.size() &&
            GEPI->getParent()->getParent() == CurBB->getParent()) {
          bool Mismatch = false;
          for (unsigned i = 0, e = GEPOps.size(); i != e; ++i)
            if (GEPI->getOperand(i) != GEPOps[i]) {
              Mismatch = true;
              break;
            }
          if (!Mismatch)
            return GEPI;
        }
    }
    return 0;
  }

  // Handle add with a constant RHS.
  if (Inst->getOpcode() == Instruction::Add &&
      isa<ConstantInt>(Inst->getOperand(1))) {
    // PHI translate the LHS.
    Constant *RHS = cast<ConstantInt>(Inst->getOperand(1));
    bool isNSW = cast<BinaryOperator>(Inst)->hasNoSignedWrap();
    bool isNUW = cast<BinaryOperator>(Inst)->hasNoUnsignedWrap();

    Value *LHS = PHITranslateSubExpr(Inst->getOperand(0), CurBB, PredBB);
    if (LHS == 0) return 0;

    // If the PHI translated LHS is an add of a constant, fold the immediates.
    if (BinaryOperator *BOp = dyn_cast<BinaryOperator>(LHS))
      if (BOp->getOpcode() == Instruction::Add)
        if (ConstantInt *CI = dyn_cast<ConstantInt>(BOp->getOperand(1))) {
          LHS = BOp->getOperand(0);
          RHS = ConstantExpr::getAdd(RHS, CI);
          isNSW = isNUW = false;
        }

    // See if the add simplifies away.
    if (Value *Res = SimplifyAddInst(LHS, RHS, isNSW, isNUW, TD))
      return Res;

    // Otherwise, see if we have this add available somewhere.
    for (Value::use_iterator UI = LHS->use_begin(), E = LHS->use_end();
         UI != E; ++UI) {
      if (BinaryOperator *BO = dyn_cast<BinaryOperator>(*UI))
        if (BO->getOperand(0) == LHS && BO->getOperand(1) == RHS &&
            BO->getParent()->getParent() == CurBB->getParent())
          return BO;
    }

    return 0;
  }

  // Otherwise, we failed.
  return 0;
}

/// PHITranslateValue - PHI translate the current address up the CFG from
/// CurBB to Pred, updating our state the reflect any needed changes.  This
/// returns true on failure and sets Addr to null.
bool PHITransAddr::PHITranslateValue(BasicBlock *CurBB, BasicBlock *PredBB) {
  Addr = PHITranslateSubExpr(Addr, CurBB, PredBB);
  return Addr == 0;
}

/// GetAvailablePHITranslatedSubExpr - Return the value computed by
/// PHITranslateSubExpr if it dominates PredBB, otherwise return null.
Value *PHITransAddr::
GetAvailablePHITranslatedSubExpr(Value *V, BasicBlock *CurBB,BasicBlock *PredBB,
                                 const DominatorTree &DT) {
  // See if PHI translation succeeds.
  V = PHITranslateSubExpr(V, CurBB, PredBB);

  // Make sure the value is live in the predecessor.
  if (Instruction *Inst = dyn_cast_or_null<Instruction>(V))
    if (!DT.dominates(Inst->getParent(), PredBB))
      return 0;
  return V;
}

/// PHITranslateWithInsertion - PHI translate this value into the specified
/// predecessor block, inserting a computation of the value if it is
/// unavailable.
///
/// All newly created instructions are added to the NewInsts list.  This
/// returns null on failure.
///
Value *PHITransAddr::
PHITranslateWithInsertion(BasicBlock *CurBB, BasicBlock *PredBB,
                          const DominatorTree &DT,
                          SmallVectorImpl<Instruction*> &NewInsts) {
  unsigned NISize = NewInsts.size();

  // Attempt to PHI translate with insertion.
  Addr = InsertPHITranslatedSubExpr(Addr, CurBB, PredBB, DT, NewInsts);

  // If successful, return the new value.
  if (Addr) return Addr;

  // If not, destroy any intermediate instructions inserted.
  while (NewInsts.size() != NISize)
    NewInsts.pop_back_val()->eraseFromParent();
  return 0;
}

/// InsertPHITranslatedPointer - Insert a computation of the PHI translated
/// version of 'V' for the edge PredBB->CurBB into the end of the PredBB
/// block.  All newly created instructions are added to the NewInsts list.
/// This returns null on failure.
///
Value *PHITransAddr::
InsertPHITranslatedSubExpr(Value *InVal, BasicBlock *CurBB,
                           BasicBlock *PredBB, const DominatorTree &DT,
                           SmallVectorImpl<Instruction*> &NewInsts) {
  // See if we have a version of this value already available and dominating
  // PredBB.  If so, there is no need to insert a new instance of it.
  if (Value *Res = GetAvailablePHITranslatedSubExpr(InVal, CurBB, PredBB, DT))
    return Res;

  // If we don't have an available version of this value, it must be an
  // instruction.
  Instruction *Inst = cast<Instruction>(InVal);

  // Handle bitcast of PHI translatable value.
  if (BitCastInst *BC = dyn_cast<BitCastInst>(Inst)) {
    Value *OpVal = InsertPHITranslatedSubExpr(BC->getOperand(0),
                                              CurBB, PredBB, DT, NewInsts);
    if (OpVal == 0) return 0;

    // Otherwise insert a bitcast at the end of PredBB.
    BitCastInst *New = new BitCastInst(OpVal, InVal->getType(),
                                       InVal->getName()+".phi.trans.insert",
                                       PredBB->getTerminator());
    NewInsts.push_back(New);
    return New;
  }

  // Handle getelementptr with at least one PHI operand.
  if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Inst)) {
    SmallVector<Value*, 8> GEPOps;
    BasicBlock *CurBB = GEP->getParent();
    for (unsigned i = 0, e = GEP->getNumOperands(); i != e; ++i) {
      Value *OpVal = InsertPHITranslatedSubExpr(GEP->getOperand(i),
                                                CurBB, PredBB, DT, NewInsts);
      if (OpVal == 0) return 0;
      GEPOps.push_back(OpVal);
    }

    GetElementPtrInst *Result =
    GetElementPtrInst::Create(GEPOps[0], GEPOps.begin()+1, GEPOps.end(),
                              InVal->getName()+".phi.trans.insert",
                              PredBB->getTerminator());
    Result->setIsInBounds(GEP->isInBounds());
    NewInsts.push_back(Result);
    return Result;
  }

#if 0
  // FIXME: This code works, but it is unclear that we actually want to insert
  // a big chain of computation in order to make a value available in a block.
  // This needs to be evaluated carefully to consider its cost trade offs.

  // Handle add with a constant RHS.
  if (Inst->getOpcode() == Instruction::Add &&
      isa<ConstantInt>(Inst->getOperand(1))) {
    // PHI translate the LHS.
    Value *OpVal = InsertPHITranslatedSubExpr(Inst->getOperand(0),
                                              CurBB, PredBB, DT, NewInsts);
    if (OpVal == 0) return 0;

    BinaryOperator *Res = BinaryOperator::CreateAdd(OpVal, Inst->getOperand(1),
                                           InVal->getName()+".phi.trans.insert",
                                                    PredBB->getTerminator());
    Res->setHasNoSignedWrap(cast<BinaryOperator>(Inst)->hasNoSignedWrap());
    Res->setHasNoUnsignedWrap(cast<BinaryOperator>(Inst)->hasNoUnsignedWrap());
    NewInsts.push_back(Res);
    return Res;
  }
#endif

  return 0;
}
<commit_msg>fix typo<commit_after>//===- PHITransAddr.cpp - PHI Translation for Addresses -------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the PHITransAddr class.
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/PHITransAddr.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/InstructionSimplify.h"
using namespace llvm;

static bool CanPHITrans(Instruction *Inst) {
  if (isa<PHINode>(Inst) ||
      isa<BitCastInst>(Inst) ||
      isa<GetElementPtrInst>(Inst))
    return true;

  if (Inst->getOpcode() == Instruction::And &&
      isa<ConstantInt>(Inst->getOperand(1)))
    return true;

  //   cerr << "MEMDEP: Could not PHI translate: " << *Pointer;
  //   if (isa<BitCastInst>(PtrInst) || isa<GetElementPtrInst>(PtrInst))
  //     cerr << "OP:\t\t\t\t" << *PtrInst->getOperand(0);
  return false;
}

/// IsPotentiallyPHITranslatable - If this needs PHI translation, return true
/// if we have some hope of doing it.  This should be used as a filter to
/// avoid calling PHITranslateValue in hopeless situations.
bool PHITransAddr::IsPotentiallyPHITranslatable() const {
  // If the input value is not an instruction, or if it is not defined in CurBB,
  // then we don't need to phi translate it.
  Instruction *Inst = dyn_cast<Instruction>(Addr);
  return Inst == 0 || CanPHITrans(Inst);
}

Value *PHITransAddr::PHITranslateSubExpr(Value *V, BasicBlock *CurBB,
                                         BasicBlock *PredBB) {
  // If this is a non-instruction value, it can't require PHI translation.
  Instruction *Inst = dyn_cast<Instruction>(V);
  if (Inst == 0) return V;

  // If 'Inst' is defined in this block, it must be an input that needs to be
  // phi translated or an intermediate expression that needs to be incorporated
  // into the expression.
  if (Inst->getParent() == CurBB) {
    assert(std::count(InstInputs.begin(), InstInputs.end(), Inst) &&
           "Not an input?");

    // If this is a PHI, go ahead and translate it.
    if (PHINode *PN = dyn_cast<PHINode>(Inst))
      return PN->getIncomingValueForBlock(PredBB);

    // If this is a non-phi value, and it is analyzable, we can incorporate it
    // into the expression by making all instruction operands be inputs.
    if (!CanPHITrans(Inst))
      return 0;

    // Okay, we can incorporate it, this instruction is no longer an input.
    InstInputs.erase(std::find(InstInputs.begin(), InstInputs.end(), Inst));

    // All instruction operands are now inputs (and of course, they may also be
    // defined in this block, so they may need to be phi translated themselves.
    for (unsigned i = 0, e = Inst->getNumOperands(); i != e; ++i)
      if (Instruction *Op = dyn_cast<Instruction>(Inst->getOperand(i)))
        InstInputs.push_back(Op);

  } else {
    // Determine whether 'Inst' is an input to our PHI translatable expression.
    bool isInput = std::count(InstInputs.begin(), InstInputs.end(), Inst);

    // If it is an input defined in a different block, then it remains an input.
    if (isInput)
      return Inst;
  }

  // Ok, it must be an intermediate result (either because it started that way
  // or because we just incorporated it into the expression).  See if its
  // operands need to be phi translated, and if so, reconstruct it.

  if (BitCastInst *BC = dyn_cast<BitCastInst>(Inst)) {
    Value *PHIIn = PHITranslateSubExpr(BC->getOperand(0), CurBB, PredBB);
    if (PHIIn == 0) return 0;
    if (PHIIn == BC->getOperand(0))
      return BC;

    // Find an available version of this cast.

    // Constants are trivial to find.
    if (Constant *C = dyn_cast<Constant>(PHIIn))
      return ConstantExpr::getBitCast(C, BC->getType());

    // Otherwise we have to see if a bitcasted version of the incoming pointer
    // is available.  If so, we can use it, otherwise we have to fail.
    for (Value::use_iterator UI = PHIIn->use_begin(), E = PHIIn->use_end();
         UI != E; ++UI) {
      if (BitCastInst *BCI = dyn_cast<BitCastInst>(*UI))
        if (BCI->getType() == BC->getType())
          return BCI;
    }
    return 0;
  }

  // Handle getelementptr with at least one PHI translatable operand.
  if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Inst)) {
    SmallVector<Value*, 8> GEPOps;
    BasicBlock *CurBB = GEP->getParent();
    bool AnyChanged = false;
    for (unsigned i = 0, e = GEP->getNumOperands(); i != e; ++i) {
      Value *GEPOp = PHITranslateSubExpr(GEP->getOperand(i), CurBB, PredBB);
      if (GEPOp == 0) return 0;

      AnyChanged |= GEPOp != GEP->getOperand(i);
      GEPOps.push_back(GEPOp);
    }

    if (!AnyChanged)
      return GEP;

    // Simplify the GEP to handle 'gep x, 0' -> x etc.
    if (Value *V = SimplifyGEPInst(&GEPOps[0], GEPOps.size(), TD))
      return V;

    // Scan to see if we have this GEP available.
    Value *APHIOp = GEPOps[0];
    for (Value::use_iterator UI = APHIOp->use_begin(), E = APHIOp->use_end();
         UI != E; ++UI) {
      if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(*UI))
        if (GEPI->getType() == GEP->getType() &&
            GEPI->getNumOperands() == GEPOps.size() &&
            GEPI->getParent()->getParent() == CurBB->getParent()) {
          bool Mismatch = false;
          for (unsigned i = 0, e = GEPOps.size(); i != e; ++i)
            if (GEPI->getOperand(i) != GEPOps[i]) {
              Mismatch = true;
              break;
            }
          if (!Mismatch)
            return GEPI;
        }
    }
    return 0;
  }

  // Handle add with a constant RHS.
  if (Inst->getOpcode() == Instruction::Add &&
      isa<ConstantInt>(Inst->getOperand(1))) {
    // PHI translate the LHS.
    Constant *RHS = cast<ConstantInt>(Inst->getOperand(1));
    bool isNSW = cast<BinaryOperator>(Inst)->hasNoSignedWrap();
    bool isNUW = cast<BinaryOperator>(Inst)->hasNoUnsignedWrap();

    Value *LHS = PHITranslateSubExpr(Inst->getOperand(0), CurBB, PredBB);
    if (LHS == 0) return 0;

    // If the PHI translated LHS is an add of a constant, fold the immediates.
    if (BinaryOperator *BOp = dyn_cast<BinaryOperator>(LHS))
      if (BOp->getOpcode() == Instruction::Add)
        if (ConstantInt *CI = dyn_cast<ConstantInt>(BOp->getOperand(1))) {
          LHS = BOp->getOperand(0);
          RHS = ConstantExpr::getAdd(RHS, CI);
          isNSW = isNUW = false;
        }

    // See if the add simplifies away.
    if (Value *Res = SimplifyAddInst(LHS, RHS, isNSW, isNUW, TD))
      return Res;

    // Otherwise, see if we have this add available somewhere.
    for (Value::use_iterator UI = LHS->use_begin(), E = LHS->use_end();
         UI != E; ++UI) {
      if (BinaryOperator *BO = dyn_cast<BinaryOperator>(*UI))
        if (BO->getOperand(0) == LHS && BO->getOperand(1) == RHS &&
            BO->getParent()->getParent() == CurBB->getParent())
          return BO;
    }

    return 0;
  }

  // Otherwise, we failed.
  return 0;
}

/// PHITranslateValue - PHI translate the current address up the CFG from
/// CurBB to Pred, updating our state the reflect any needed changes.  This
/// returns true on failure and sets Addr to null.
bool PHITransAddr::PHITranslateValue(BasicBlock *CurBB, BasicBlock *PredBB) {
  Addr = PHITranslateSubExpr(Addr, CurBB, PredBB);
  return Addr == 0;
}

/// GetAvailablePHITranslatedSubExpr - Return the value computed by
/// PHITranslateSubExpr if it dominates PredBB, otherwise return null.
Value *PHITransAddr::
GetAvailablePHITranslatedSubExpr(Value *V, BasicBlock *CurBB,BasicBlock *PredBB,
                                 const DominatorTree &DT) {
  // See if PHI translation succeeds.
  V = PHITranslateSubExpr(V, CurBB, PredBB);

  // Make sure the value is live in the predecessor.
  if (Instruction *Inst = dyn_cast_or_null<Instruction>(V))
    if (!DT.dominates(Inst->getParent(), PredBB))
      return 0;
  return V;
}

/// PHITranslateWithInsertion - PHI translate this value into the specified
/// predecessor block, inserting a computation of the value if it is
/// unavailable.
///
/// All newly created instructions are added to the NewInsts list.  This
/// returns null on failure.
///
Value *PHITransAddr::
PHITranslateWithInsertion(BasicBlock *CurBB, BasicBlock *PredBB,
                          const DominatorTree &DT,
                          SmallVectorImpl<Instruction*> &NewInsts) {
  unsigned NISize = NewInsts.size();

  // Attempt to PHI translate with insertion.
  Addr = InsertPHITranslatedSubExpr(Addr, CurBB, PredBB, DT, NewInsts);

  // If successful, return the new value.
  if (Addr) return Addr;

  // If not, destroy any intermediate instructions inserted.
  while (NewInsts.size() != NISize)
    NewInsts.pop_back_val()->eraseFromParent();
  return 0;
}

/// InsertPHITranslatedPointer - Insert a computation of the PHI translated
/// version of 'V' for the edge PredBB->CurBB into the end of the PredBB
/// block.  All newly created instructions are added to the NewInsts list.
/// This returns null on failure.
///
Value *PHITransAddr::
InsertPHITranslatedSubExpr(Value *InVal, BasicBlock *CurBB,
                           BasicBlock *PredBB, const DominatorTree &DT,
                           SmallVectorImpl<Instruction*> &NewInsts) {
  // See if we have a version of this value already available and dominating
  // PredBB.  If so, there is no need to insert a new instance of it.
  if (Value *Res = GetAvailablePHITranslatedSubExpr(InVal, CurBB, PredBB, DT))
    return Res;

  // If we don't have an available version of this value, it must be an
  // instruction.
  Instruction *Inst = cast<Instruction>(InVal);

  // Handle bitcast of PHI translatable value.
  if (BitCastInst *BC = dyn_cast<BitCastInst>(Inst)) {
    Value *OpVal = InsertPHITranslatedSubExpr(BC->getOperand(0),
                                              CurBB, PredBB, DT, NewInsts);
    if (OpVal == 0) return 0;

    // Otherwise insert a bitcast at the end of PredBB.
    BitCastInst *New = new BitCastInst(OpVal, InVal->getType(),
                                       InVal->getName()+".phi.trans.insert",
                                       PredBB->getTerminator());
    NewInsts.push_back(New);
    return New;
  }

  // Handle getelementptr with at least one PHI operand.
  if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Inst)) {
    SmallVector<Value*, 8> GEPOps;
    BasicBlock *CurBB = GEP->getParent();
    for (unsigned i = 0, e = GEP->getNumOperands(); i != e; ++i) {
      Value *OpVal = InsertPHITranslatedSubExpr(GEP->getOperand(i),
                                                CurBB, PredBB, DT, NewInsts);
      if (OpVal == 0) return 0;
      GEPOps.push_back(OpVal);
    }

    GetElementPtrInst *Result =
    GetElementPtrInst::Create(GEPOps[0], GEPOps.begin()+1, GEPOps.end(),
                              InVal->getName()+".phi.trans.insert",
                              PredBB->getTerminator());
    Result->setIsInBounds(GEP->isInBounds());
    NewInsts.push_back(Result);
    return Result;
  }

#if 0
  // FIXME: This code works, but it is unclear that we actually want to insert
  // a big chain of computation in order to make a value available in a block.
  // This needs to be evaluated carefully to consider its cost trade offs.

  // Handle add with a constant RHS.
  if (Inst->getOpcode() == Instruction::Add &&
      isa<ConstantInt>(Inst->getOperand(1))) {
    // PHI translate the LHS.
    Value *OpVal = InsertPHITranslatedSubExpr(Inst->getOperand(0),
                                              CurBB, PredBB, DT, NewInsts);
    if (OpVal == 0) return 0;

    BinaryOperator *Res = BinaryOperator::CreateAdd(OpVal, Inst->getOperand(1),
                                           InVal->getName()+".phi.trans.insert",
                                                    PredBB->getTerminator());
    Res->setHasNoSignedWrap(cast<BinaryOperator>(Inst)->hasNoSignedWrap());
    Res->setHasNoUnsignedWrap(cast<BinaryOperator>(Inst)->hasNoUnsignedWrap());
    NewInsts.push_back(Res);
    return Res;
  }
#endif

  return 0;
}
<|endoftext|>