<commit_before>/*=========================================================================

  Program:   MetaIO
  Module:    metaSurface.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#ifdef _MSC_VER
#pragma warning(disable:4702)
#pragma warning(disable:4284)
#endif

#include "metaSurface.h"

#include <stdio.h>
#include <ctype.h>
#include <string>

#if (METAIO_USE_NAMESPACE)
namespace METAIO_NAMESPACE {
#endif

SurfacePnt::
SurfacePnt(int dim)
{
  m_Dim = dim;
  m_X = new float[m_Dim];
  m_V = new float[m_Dim];
  for(unsigned int i=0;i<m_Dim;i++)
    {
    m_X[i] = 0;
    m_V[i] = 0;
    }
  //Color is red by default
  m_Color[0]=1.0;
  m_Color[1]=0.0;
  m_Color[2]=0.0;
  m_Color[3]=1.0;
}

SurfacePnt::
~SurfacePnt()
{
  delete []m_X;
  delete []m_V;
}

//
// MetaSurface Constructors
//
MetaSurface::
MetaSurface()
:MetaObject()
{
  if(META_DEBUG) METAIO_STREAM::cout << "MetaSurface()" << METAIO_STREAM::endl;
  Clear();
}

//
MetaSurface::
MetaSurface(const char *_headerName)
:MetaObject()
{
  if(META_DEBUG)  METAIO_STREAM::cout << "MetaSurface()" << METAIO_STREAM::endl;
  Clear();
  Read(_headerName);
}

//
MetaSurface::
MetaSurface(const MetaSurface *_surface)
:MetaObject()
{
  if(META_DEBUG)  METAIO_STREAM::cout << "MetaSurface()" << METAIO_STREAM::endl;
  Clear();
  CopyInfo(_surface);
}

//
MetaSurface::
MetaSurface(unsigned int dim)
:MetaObject(dim)
{
  if(META_DEBUG) METAIO_STREAM::cout << "MetaSurface()" << METAIO_STREAM::endl;
  Clear();
}

//
MetaSurface::
~MetaSurface()
{
  Clear();

  M_Destroy();
}

//
void MetaSurface::
PrintInfo() const
{
  MetaObject::PrintInfo();
  METAIO_STREAM::cout << "PointDim = " << m_PointDim << METAIO_STREAM::endl;
  METAIO_STREAM::cout << "NPoints = " << m_NPoints << METAIO_STREAM::endl;
  char str[255];
  MET_TypeToString(m_ElementType, str);
  METAIO_STREAM::cout << "ElementType = " << str << METAIO_STREAM::endl;
}

void MetaSurface::
CopyInfo(const MetaObject * _object)
{
  MetaObject::CopyInfo(_object);
}

void MetaSurface::
PointDim(const char* pointDim)
{
  strcpy(m_PointDim,pointDim);
}

const char* MetaSurface::
PointDim(void) const
{
  return m_PointDim;
}

void MetaSurface::
NPoints(int npnt)
{
  m_NPoints = npnt;
}

int MetaSurface::
NPoints(void) const
{
  return m_NPoints;
}

/** Clear Surface information */
void MetaSurface::
Clear(void)
{
  if(META_DEBUG) METAIO_STREAM::cout << "MetaSurface: Clear" << METAIO_STREAM::endl;
  MetaObject::Clear();
  m_NPoints = 0;
  // Delete the list of pointers to tubes.
  PointListType::iterator it = m_PointList.begin();
  while(it != m_PointList.end())
  {
    SurfacePnt* pnt = *it;
    it++;
    delete pnt;
  }
  m_PointList.clear();
  strcpy(m_PointDim, "x y z v1x v1y v1z r g b");
  m_ElementType = MET_FLOAT;
}

/** Destroy Surface information */
void MetaSurface::
M_Destroy(void)
{
  MetaObject::M_Destroy();
}

/** Set Read fields */
void MetaSurface::
M_SetupReadFields(void)
{
  if(META_DEBUG) METAIO_STREAM::cout << "MetaSurface: M_SetupReadFields" << METAIO_STREAM::endl;

  MetaObject::M_SetupReadFields();

  MET_FieldRecordType * mF;

  mF = new MET_FieldRecordType;
  MET_InitReadField(mF, "PointDim", MET_STRING, true);
  m_Fields.push_back(mF);

  mF = new MET_FieldRecordType;
  MET_InitReadField(mF, "NPoints", MET_INT, true);
  m_Fields.push_back(mF);

  mF = new MET_FieldRecordType;
  MET_InitReadField(mF, "ElementType", MET_STRING, true);
  mF->required = true;
  m_Fields.push_back(mF);

  mF = new MET_FieldRecordType;
  MET_InitReadField(mF, "Points", MET_NONE, true);
  mF->terminateRead = true;
  m_Fields.push_back(mF);

}

void MetaSurface::
M_SetupWriteFields(void)
{
  if(META_DEBUG) METAIO_STREAM::cout << "MetaSurface: M_SetupWriteFields" << METAIO_STREAM::endl;

  strcpy(m_ObjectTypeName,"Surface");
  MetaObject::M_SetupWriteFields();

  MET_FieldRecordType * mF;

  char s[255];
  mF = new MET_FieldRecordType;
  MET_TypeToString(m_ElementType, s);
  MET_InitWriteField(mF, "ElementType", MET_STRING, strlen(s), s);
  m_Fields.push_back(mF);

  if(strlen(m_PointDim)>0)
  {
    mF = new MET_FieldRecordType;
    MET_InitWriteField(mF, "PointDim", MET_STRING,
                           strlen(m_PointDim),m_PointDim);
    m_Fields.push_back(mF);
  }

  m_NPoints = m_PointList.size();
  mF = new MET_FieldRecordType;
  MET_InitWriteField(mF, "NPoints", MET_INT,m_NPoints);
  m_Fields.push_back(mF);

  mF = new MET_FieldRecordType;
  MET_InitWriteField(mF, "Points", MET_NONE);
  m_Fields.push_back(mF);

}

MET_ValueEnumType MetaSurface::
ElementType(void) const
{
  return m_ElementType;
}

void MetaSurface::
ElementType(MET_ValueEnumType _elementType)
{
  m_ElementType = _elementType;
}

bool MetaSurface::
M_Read(void)
{
  if(META_DEBUG) METAIO_STREAM::cout << "MetaSurface: M_Read: Loading Header" << METAIO_STREAM::endl;

  if(!MetaObject::M_Read())
  {
    METAIO_STREAM::cout << "MetaSurface: M_Read: Error parsing file" << METAIO_STREAM::endl;
    return false;
  }

  if(META_DEBUG) METAIO_STREAM::cout << "MetaSurface: M_Read: Parsing Header" << METAIO_STREAM::endl;

  MET_FieldRecordType * mF;

  mF = MET_GetFieldRecord("NPoints", &m_Fields);
  if(mF->defined)
  {
    m_NPoints= (int)mF->value[0];
  }

  mF = MET_GetFieldRecord("ElementType", &m_Fields);
  if(mF->defined)
  {
    MET_StringToType((char *)(mF->value), &m_ElementType);
  }

  mF = MET_GetFieldRecord("PointDim", &m_Fields);
  if(mF->defined)
  {
    strcpy(m_PointDim,(char *)(mF->value));
  }

  int pntDim;
  char** pntVal = NULL;
  MET_StringToWordArray(m_PointDim, &pntDim, &pntVal);

  int i;
  for(i=0;i<pntDim;i++)
    {
      delete [] pntVal[i];
    }
  delete [] pntVal;

  float v[16];

  if(m_BinaryData)
  {
    int elementSize;
    MET_SizeOfType(m_ElementType, &elementSize);
    int readSize = m_NPoints*(m_NDims*2+4)*elementSize;

    char* _data = new char[readSize];
    m_ReadStream->read((char *)_data, readSize);

    int gc = m_ReadStream->gcount();
    if(gc != readSize)
    {
      METAIO_STREAM::cout << "MetaSurface: m_Read: data not read completely"
                << METAIO_STREAM::endl;
      METAIO_STREAM::cout << "   ideal = " << readSize << " : actual = " << gc << METAIO_STREAM::endl;
      return false;
    }

    i=0;
    int d;
    unsigned int k;
    for(int j=0; j<m_NPoints; j++)
    {
      SurfacePnt* pnt = new SurfacePnt(m_NDims);

      for(d=0; d<m_NDims; d++)
      {
        char* num = new char[sizeof(float)];
        for(k=0;k<sizeof(float);k++)
          {
          num[k] = _data[i+k];
          }
        float td = (float)((float*)num)[0];
        MET_SwapByteIfSystemMSB(&td,MET_FLOAT);
        i+=sizeof(float);
        pnt->m_X[d] = (float)td;
        delete [] num;
      }

      for(d=0; d<m_NDims; d++)
      {
        char* num = new char[sizeof(float)];
        for(k=0;k<sizeof(float);k++)
          {
          num[k] = _data[i+k];
          }
        float td = (float)((float*)num)[0];
        MET_SwapByteIfSystemMSB(&td,MET_FLOAT);
        i+=sizeof(float);
        pnt->m_V[d] = (float)td;
        delete [] num;
      }

       for(d=0; d<4; d++)
      {
        char* num = new char[sizeof(float)];
        for(k=0;k<sizeof(float);k++)
          {
          num[k] = _data[i+k];
          }
        float td = (float)((float*)num)[0];
        MET_SwapByteIfSystemMSB(&td,MET_FLOAT);
        i+=sizeof(float);
        pnt->m_Color[d] = (float)td;
        delete [] num;
      }
      m_PointList.push_back(pnt);
    }
    delete [] _data;
  }
  else
  {
    for(int j=0; j<m_NPoints; j++)
    {
      SurfacePnt* pnt = new SurfacePnt(m_NDims);

      for(int k=0; k<pntDim; k++)
      {
        *m_ReadStream >> v[k];
        m_ReadStream->get(); // char c =
      }

      int d;
      for(d=0; d<m_NDims; d++)
      {
        pnt->m_X[d] = v[d];
      }

      for(d=m_NDims; d<m_NDims*2; d++)
      {
        pnt->m_V[d-m_NDims] = v[d];
      }

      for(d=0; d<4; d++)
      {
        pnt->m_Color[d] = v[d+2*m_NDims];
      }

      m_PointList.push_back(pnt);
    }

    char c = ' ';
    while( (c!='\n') && (!m_ReadStream->eof()))
    {
      c = m_ReadStream->get();// to avoid unrecognize charactere
    }
  }

  return true;
}

bool MetaSurface::
M_Write(void)
{

  if(META_DEBUG) METAIO_STREAM::cout << "MetaSurface: M_Write" << METAIO_STREAM::endl;

  if(!MetaObject::M_Write())
  {
    METAIO_STREAM::cout << "MetaSurface: M_Read: Error parsing file" << METAIO_STREAM::endl;
    return false;
  }

  /** Then copy all points */

  if(m_BinaryData)
  {
    PointListType::const_iterator it = m_PointList.begin();
    PointListType::const_iterator itEnd = m_PointList.end();
    int elementSize;
    MET_SizeOfType(m_ElementType, &elementSize);

    char* data = new char[(m_NDims*2+4)*m_NPoints*elementSize];
    int i=0;
    int d;
    while(it != m_PointList.end())
    {
      for(d = 0; d < m_NDims; d++)
      {
        float x = (*it)->m_X[d];
        MET_SwapByteIfSystemMSB(&x,MET_FLOAT);
        MET_DoubleToValue((double)x,m_ElementType,data,i++);
      }

      for(d = 0; d < m_NDims; d++)
      {
        float v = (*it)->m_V[d];
        MET_SwapByteIfSystemMSB(&v,MET_FLOAT);
        MET_DoubleToValue((double)v,m_ElementType,data,i++);
      }

      for(d=0; d<4; d++)
      {
        float c = (*it)->m_Color[d];
        MET_SwapByteIfSystemMSB(&c,MET_FLOAT);
        MET_DoubleToValue((double)c,m_ElementType,data,i++);
      }

      it++;
    }

    m_WriteStream->write((char *)data,(m_NDims*2+4)*m_NPoints*elementSize);
    m_WriteStream->write("\n",1);
    delete [] data;
  }
  else
  {
    PointListType::const_iterator it = m_PointList.begin();
    PointListType::const_iterator itEnd = m_PointList.end();

    int d;
    while(it != m_PointList.end())
    {
      for(d = 0; d < m_NDims; d++)
      {
        *m_WriteStream << (*it)->m_X[d] << " ";
      }

      for(d = 0; d < m_NDims; d++)
      {
        *m_WriteStream << (*it)->m_V[d] << " ";
      }

      for(d=0;d<4;d++)
      {
        *m_WriteStream << (*it)->m_Color[d] << " ";
      }

      *m_WriteStream << METAIO_STREAM::endl;
      it++;
    }
  }

  return true;

}

#if (METAIO_USE_NAMESPACE)
};
#endif

<commit_msg>COMP: Programmer IQ error - didn't complete resolving of HPUX error<commit_after>/*=========================================================================

  Program:   MetaIO
  Module:    metaSurface.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#ifdef _MSC_VER
#pragma warning(disable:4702)
#pragma warning(disable:4284)
#endif

#include "metaSurface.h"

#include <stdio.h>
#include <ctype.h>
#include <string>

#if (METAIO_USE_NAMESPACE)
namespace METAIO_NAMESPACE {
#endif

SurfacePnt::
SurfacePnt(int dim)
{
  m_Dim = dim;
  m_X = new float[m_Dim];
  m_V = new float[m_Dim];
  for(unsigned int i=0;i<m_Dim;i++)
    {
    m_X[i] = 0;
    m_V[i] = 0;
    }
  //Color is red by default
  m_Color[0]=1.0;
  m_Color[1]=0.0;
  m_Color[2]=0.0;
  m_Color[3]=1.0;
}

SurfacePnt::
~SurfacePnt()
{
  delete []m_X;
  delete []m_V;
}

//
// MetaSurface Constructors
//
MetaSurface::
MetaSurface()
:MetaObject()
{
  if(META_DEBUG) METAIO_STREAM::cout << "MetaSurface()" << METAIO_STREAM::endl;
  Clear();
}

//
MetaSurface::
MetaSurface(const char *_headerName)
:MetaObject()
{
  if(META_DEBUG)  METAIO_STREAM::cout << "MetaSurface()" << METAIO_STREAM::endl;
  Clear();
  Read(_headerName);
}

//
MetaSurface::
MetaSurface(const MetaSurface *_surface)
:MetaObject()
{
  if(META_DEBUG)  METAIO_STREAM::cout << "MetaSurface()" << METAIO_STREAM::endl;
  Clear();
  CopyInfo(_surface);
}

//
MetaSurface::
MetaSurface(unsigned int dim)
:MetaObject(dim)
{
  if(META_DEBUG) METAIO_STREAM::cout << "MetaSurface()" << METAIO_STREAM::endl;
  Clear();
}

//
MetaSurface::
~MetaSurface()
{
  Clear();

  M_Destroy();
}

//
void MetaSurface::
PrintInfo() const
{
  MetaObject::PrintInfo();
  METAIO_STREAM::cout << "PointDim = " << m_PointDim << METAIO_STREAM::endl;
  METAIO_STREAM::cout << "NPoints = " << m_NPoints << METAIO_STREAM::endl;
  char str[255];
  MET_TypeToString(m_ElementType, str);
  METAIO_STREAM::cout << "ElementType = " << str << METAIO_STREAM::endl;
}

void MetaSurface::
CopyInfo(const MetaObject * _object)
{
  MetaObject::CopyInfo(_object);
}

void MetaSurface::
PointDim(const char* pointDim)
{
  strcpy(m_PointDim,pointDim);
}

const char* MetaSurface::
PointDim(void) const
{
  return m_PointDim;
}

void MetaSurface::
NPoints(int npnt)
{
  m_NPoints = npnt;
}

int MetaSurface::
NPoints(void) const
{
  return m_NPoints;
}

/** Clear Surface information */
void MetaSurface::
Clear(void)
{
  if(META_DEBUG) METAIO_STREAM::cout << "MetaSurface: Clear" << METAIO_STREAM::endl;
  MetaObject::Clear();
  m_NPoints = 0;
  // Delete the list of pointers to tubes.
  PointListType::iterator it = m_PointList.begin();
  while(it != m_PointList.end())
  {
    SurfacePnt* pnt = *it;
    it++;
    delete pnt;
  }
  m_PointList.clear();
  strcpy(m_PointDim, "x y z v1x v1y v1z r g b");
  m_ElementType = MET_FLOAT;
}

/** Destroy Surface information */
void MetaSurface::
M_Destroy(void)
{
  MetaObject::M_Destroy();
}

/** Set Read fields */
void MetaSurface::
M_SetupReadFields(void)
{
  if(META_DEBUG) METAIO_STREAM::cout << "MetaSurface: M_SetupReadFields" << METAIO_STREAM::endl;

  MetaObject::M_SetupReadFields();

  MET_FieldRecordType * mF;

  mF = new MET_FieldRecordType;
  MET_InitReadField(mF, "PointDim", MET_STRING, true);
  m_Fields.push_back(mF);

  mF = new MET_FieldRecordType;
  MET_InitReadField(mF, "NPoints", MET_INT, true);
  m_Fields.push_back(mF);

  mF = new MET_FieldRecordType;
  MET_InitReadField(mF, "ElementType", MET_STRING, true);
  mF->required = true;
  m_Fields.push_back(mF);

  mF = new MET_FieldRecordType;
  MET_InitReadField(mF, "Points", MET_NONE, true);
  mF->terminateRead = true;
  m_Fields.push_back(mF);

}

void MetaSurface::
M_SetupWriteFields(void)
{
  if(META_DEBUG) METAIO_STREAM::cout << "MetaSurface: M_SetupWriteFields" << METAIO_STREAM::endl;

  strcpy(m_ObjectTypeName,"Surface");
  MetaObject::M_SetupWriteFields();

  MET_FieldRecordType * mF;

  char s[255];
  mF = new MET_FieldRecordType;
  MET_TypeToString(m_ElementType, s);
  MET_InitWriteField(mF, "ElementType", MET_STRING, strlen(s), s);
  m_Fields.push_back(mF);

  if(strlen(m_PointDim)>0)
  {
    mF = new MET_FieldRecordType;
    MET_InitWriteField(mF, "PointDim", MET_STRING,
                           strlen(m_PointDim),m_PointDim);
    m_Fields.push_back(mF);
  }

  m_NPoints = m_PointList.size();
  mF = new MET_FieldRecordType;
  MET_InitWriteField(mF, "NPoints", MET_INT,m_NPoints);
  m_Fields.push_back(mF);

  mF = new MET_FieldRecordType;
  MET_InitWriteField(mF, "Points", MET_NONE);
  m_Fields.push_back(mF);

}

MET_ValueEnumType MetaSurface::
ElementType(void) const
{
  return m_ElementType;
}

void MetaSurface::
ElementType(MET_ValueEnumType _elementType)
{
  m_ElementType = _elementType;
}

bool MetaSurface::
M_Read(void)
{
  if(META_DEBUG) METAIO_STREAM::cout << "MetaSurface: M_Read: Loading Header" << METAIO_STREAM::endl;

  if(!MetaObject::M_Read())
  {
    METAIO_STREAM::cout << "MetaSurface: M_Read: Error parsing file" << METAIO_STREAM::endl;
    return false;
  }

  if(META_DEBUG) METAIO_STREAM::cout << "MetaSurface: M_Read: Parsing Header" << METAIO_STREAM::endl;

  MET_FieldRecordType * mF;

  mF = MET_GetFieldRecord("NPoints", &m_Fields);
  if(mF->defined)
  {
    m_NPoints= (int)mF->value[0];
  }

  mF = MET_GetFieldRecord("ElementType", &m_Fields);
  if(mF->defined)
  {
    MET_StringToType((char *)(mF->value), &m_ElementType);
  }

  mF = MET_GetFieldRecord("PointDim", &m_Fields);
  if(mF->defined)
  {
    strcpy(m_PointDim,(char *)(mF->value));
  }

  int pntDim;
  char** pntVal = NULL;
  MET_StringToWordArray(m_PointDim, &pntDim, &pntVal);

  int i;
  for(i=0;i<pntDim;i++)
    {
      delete [] pntVal[i];
    }
  delete [] pntVal;

  float v[16];

  if(m_BinaryData)
  {
    int elementSize;
    MET_SizeOfType(m_ElementType, &elementSize);
    int readSize = m_NPoints*(m_NDims*2+4)*elementSize;

    char* _data = new char[readSize];
    m_ReadStream->read((char *)_data, readSize);

    int gc = m_ReadStream->gcount();
    if(gc != readSize)
    {
      METAIO_STREAM::cout << "MetaSurface: m_Read: data not read completely"
                << METAIO_STREAM::endl;
      METAIO_STREAM::cout << "   ideal = " << readSize << " : actual = " << gc << METAIO_STREAM::endl;
      return false;
    }

    i=0;
    int d;
    unsigned int k;
    for(int j=0; j<m_NPoints; j++)
    {
      SurfacePnt* pnt = new SurfacePnt(m_NDims);

      for(d=0; d<m_NDims; d++)
      {
        char* num = new char[sizeof(float)];
        for(k=0;k<sizeof(float);k++)
          {
          num[k] = _data[i+k];
          }
        float td = (float)((float*)num)[0];
        MET_SwapByteIfSystemMSB(&td,MET_FLOAT);
        i+=sizeof(float);
        pnt->m_X[d] = (float)td;
        delete [] num;
      }

      for(d=0; d<m_NDims; d++)
      {
        char* num = new char[sizeof(float)];
        for(k=0;k<sizeof(float);k++)
          {
          num[k] = _data[i+k];
          }
        float td = (float)((float*)num)[0];
        MET_SwapByteIfSystemMSB(&td,MET_FLOAT);
        i+=sizeof(float);
        pnt->m_V[d] = (float)td;
        delete [] num;
      }

       for(d=0; d<4; d++)
      {
        char* num = new char[sizeof(float)];
        for(k=0;k<sizeof(float);k++)
          {
          num[k] = _data[i+k];
          }
        float td = (float)((float*)num)[0];
        MET_SwapByteIfSystemMSB(&td,MET_FLOAT);
        i+=sizeof(float);
        pnt->m_Color[d] = (float)td;
        delete [] num;
      }
      m_PointList.push_back(pnt);
    }
    delete [] _data;
  }
  else
  {
    for(int j=0; j<m_NPoints; j++)
    {
      SurfacePnt* pnt = new SurfacePnt(m_NDims);

      for(int k=0; k<pntDim; k++)
      {
        *m_ReadStream >> v[k];
        m_ReadStream->get(); // char c =
      }

      int d;
      for(d=0; d<m_NDims; d++)
      {
        pnt->m_X[d] = v[d];
      }

      for(d=m_NDims; d<m_NDims*2; d++)
      {
        pnt->m_V[d-m_NDims] = v[d];
      }

      for(d=0; d<4; d++)
      {
        pnt->m_Color[d] = v[d+2*m_NDims];
      }

      m_PointList.push_back(pnt);
    }

    char c = ' ';
    while( (c!='\n') && (!m_ReadStream->eof()))
    {
      c = m_ReadStream->get();// to avoid unrecognize charactere
    }
  }

  return true;
}

bool MetaSurface::
M_Write(void)
{

  if(META_DEBUG) METAIO_STREAM::cout << "MetaSurface: M_Write" << METAIO_STREAM::endl;

  if(!MetaObject::M_Write())
  {
    METAIO_STREAM::cout << "MetaSurface: M_Read: Error parsing file" << METAIO_STREAM::endl;
    return false;
  }

  /** Then copy all points */

  if(m_BinaryData)
  {
    PointListType::const_iterator it = m_PointList.begin();
    PointListType::const_iterator itEnd = m_PointList.end();
    int elementSize;
    MET_SizeOfType(m_ElementType, &elementSize);

    char* data = new char[(m_NDims*2+4)*m_NPoints*elementSize];
    int i=0;
    int d;
    while(it != itEnd)
    {
      for(d = 0; d < m_NDims; d++)
      {
        float x = (*it)->m_X[d];
        MET_SwapByteIfSystemMSB(&x,MET_FLOAT);
        MET_DoubleToValue((double)x,m_ElementType,data,i++);
      }

      for(d = 0; d < m_NDims; d++)
      {
        float v = (*it)->m_V[d];
        MET_SwapByteIfSystemMSB(&v,MET_FLOAT);
        MET_DoubleToValue((double)v,m_ElementType,data,i++);
      }

      for(d=0; d<4; d++)
      {
        float c = (*it)->m_Color[d];
        MET_SwapByteIfSystemMSB(&c,MET_FLOAT);
        MET_DoubleToValue((double)c,m_ElementType,data,i++);
      }

      it++;
    }

    m_WriteStream->write((char *)data,(m_NDims*2+4)*m_NPoints*elementSize);
    m_WriteStream->write("\n",1);
    delete [] data;
  }
  else
  {
    PointListType::const_iterator it = m_PointList.begin();
    PointListType::const_iterator itEnd = m_PointList.end();

    int d;
    while(it != itEnd)
    {
      for(d = 0; d < m_NDims; d++)
      {
        *m_WriteStream << (*it)->m_X[d] << " ";
      }

      for(d = 0; d < m_NDims; d++)
      {
        *m_WriteStream << (*it)->m_V[d] << " ";
      }

      for(d=0;d<4;d++)
      {
        *m_WriteStream << (*it)->m_Color[d] << " ";
      }

      *m_WriteStream << METAIO_STREAM::endl;
      it++;
    }
  }

  return true;

}

#if (METAIO_USE_NAMESPACE)
};
#endif

<|endoftext|>


<commit_before>#include <chrono>
#include <memory>
#include <iostream>
#include <SFML/Graphics.hpp>
#include <Wind/Engine/Body/Body.hpp>
#include <Wind/Engine/Shape/Shape.hpp>
#include <Wind/Engine/Shape/CircleShape.hpp>
#include <Wind/Engine/Entity/Entity.hpp>
#include <Wind/Engine/Engine/Engine.hpp>
#include <Wind/Engine/Partitioning/QuadTree.hpp>
#include <Wind/Engine/Integration/RK4.hpp>
#include <Wind/Engine/Integration/Euler.hpp>

void draw_quadtree(sf::RenderWindow &window, const wind::QuadTree *tree);

int main()
{
	sf::RenderWindow window{{800, 600}, "Windtunnel"};
	window.setFramerateLimit(1000);

	// Basic particle shape
	sf::CircleShape particle_drawable;
	particle_drawable.setRadius(0.75f);
	particle_drawable.setFillColor(sf::Color::Red);

	std::shared_ptr<wind::QuadTree> quadtree = std::make_shared<wind::QuadTree>(
		wind::QuadTree{{
			{window.getSize().x/2.f, window.getSize().y/2.f},
			{window.getSize().x/2.f, window.getSize().y/2.f}
		}}
	);

	quadtree->max_depth = 5;
	quadtree->max_elements_before_split = 10;

	wind::Engine engine;

	engine.set_integrator(wind::Integrators::RK4);

	bool render_quadtree=true;
	engine.use_quadtree = true;
	engine.set_quadtree(quadtree);

	// Create array of physics objects
	wind::Vector2u amount{20, 20};
	std::vector<std::shared_ptr<wind::Entity>> particles;
	particles.resize(amount.x*amount.y);
	std::cout<<"num_particles: "<<particles.size()<<std::endl;

	// Create particle shapes and bodies
	std::shared_ptr<wind::Body> particle_body=std::make_shared<wind::Body>();
	std::shared_ptr<wind::Shape> particle_shape=std::make_shared<wind::CircleShape>(0.75f);
	particle_body->add_shape(particle_shape);

	// Assign particle positions
	for(auto particle_index=0; particle_index < particles.size(); ++particle_index)
	{
		auto& particle = particles[particle_index];
		particle = std::make_shared<wind::Entity>();

		particle->position.x = particle_index%amount.y+1;
		particle->position.y = particle_index/amount.x+1;
		particle->position.x*= window.getSize().x/(amount.x+1);
		particle->position.y*= window.getSize().y/(amount.y+1);
		particle->mass = 10000.f;
		particle->gravity_exert=true;
		particle->gravity_affected=true;

		particle->set_body(particle_body);

		engine.add_entity(particle);
	}

	// Used for calculating frametimes
	auto frame_start = std::chrono::high_resolution_clock::now();
	while(window.isOpen())
	{
		auto frame_duration = std::chrono::high_resolution_clock::now() - frame_start;
		frame_start = std::chrono::high_resolution_clock::now();

		auto frame_duration_us = std::chrono::duration_cast<std::chrono::microseconds>(frame_duration);
		auto frametime_us = frame_duration_us.count();
		auto frametime_ms = frametime_us/1000.f;
		auto frametime_s  = frametime_ms/1000.f;

		window.setTitle(
			"Windtunnel :: [FPS] " + std::to_string(1.f/(frametime_s)) +
			"\t:: [Frametime] " + std::to_string(frametime_us) + "us"
		);

		sf::Event event;
		while(window.pollEvent(event))
		{
			switch(event.type)
			{
			case sf::Event::Closed:
				window.close();
				break;
			case sf::Event::KeyReleased:
				switch(event.key.code)
				{
				case sf::Keyboard::G:
					engine.gravity = !engine.gravity;
					break;
				case sf::Keyboard::Q:
					engine.use_quadtree = !engine.use_quadtree;
					break;
				case sf::Keyboard::R:
					render_quadtree = !render_quadtree;
					break;
				default:
					break;
				}
			default:
				break;
			}
		}

		window.clear(sf::Color::Black);

		engine.simulate(wind::Engine::StandardDuration(30.f));

		if(render_quadtree)draw_quadtree(window, quadtree.get());

		for(auto& particle : particles)
		{
			particle_drawable.setPosition(particle->position.x, particle->position.y);
			window.draw(particle_drawable);
		}
		window.display();

	}
}

void draw_quadtree(sf::RenderWindow &window, const wind::QuadTree *tree)
{
	if(tree->get_nodes()!=nullptr)
	{
		draw_quadtree(window, &(tree->get_nodes()[0]));
		draw_quadtree(window, &(tree->get_nodes()[1]));
		draw_quadtree(window, &(tree->get_nodes()[2]));
		draw_quadtree(window, &(tree->get_nodes()[3]));
	}
	else
	{
		sf::RectangleShape shape;
		shape.setFillColor({0,0,0,0});
		if(tree->get_entities().empty())
		{
			shape.setOutlineColor({255,0,0, 127});
			shape.setOutlineThickness(2);
		}
		else
		{
			shape.setOutlineColor({0,255,0, 127});
			shape.setOutlineThickness(2);
		}
		shape.setPosition({tree->get_bounds().center.x-tree->get_bounds().half_size.x+2.f, tree->get_bounds().center.y-tree->get_bounds().half_size.y+2.f});
		shape.setSize({tree->get_bounds().half_size.x*2.f-2.f,tree->get_bounds().half_size.y*2.f-2.f});
		window.draw(shape);
	}
}
<commit_msg>Examples: testbench: Updated testbench to use latest implemented features<commit_after>#include <chrono>
#include <memory>
#include <iostream>
#include <SFML/Graphics.hpp>
#include <Wind/Engine/Body/Body.hpp>
#include <Wind/Engine/Shape/Shape.hpp>
#include <Wind/Engine/Shape/CircleShape.hpp>
#include <Wind/Engine/Shape/RectangleShape.hpp>
#include <Wind/Engine/Entity/Entity.hpp>
#include <Wind/Engine/Engine/Engine.hpp>
#include <Wind/Engine/Partitioning/QuadTree.hpp>
#include <Wind/Engine/Partitioning/Grid.hpp>
#include <Wind/Engine/Partitioning/Partitioning.hpp>
#include <Wind/Engine/Integration/RK4.hpp>
#include <Wind/Engine/Integration/Euler.hpp>

void draw_quadtree(sf::RenderWindow &window, const wind::QuadTree *tree);
void draw_grid(sf::RenderWindow &window, const wind::Grid *grid);

int main()
{
	sf::RenderWindow window{{800, 600}, "Windtunnel"};
	window.setFramerateLimit(6000);

	// Basic particle shape
	sf::CircleShape particle_drawable;
	particle_drawable.setRadius(0.75f);
	particle_drawable.setFillColor(sf::Color::Red);

	bool use_grid=true;

	std::shared_ptr<wind::Grid> grid = std::make_shared<wind::Grid>(
		wind::Grid{{
				{window.getSize().x/2.f, window.getSize().y/2.f},
				{window.getSize().x/2.f, window.getSize().y/2.f}
			},
			{window.getSize().x/64.f, window.getSize().y/64.f}
		}
	);

	std::shared_ptr<wind::QuadTree> quadtree = std::make_shared<wind::QuadTree>(
		wind::QuadTree{{
			{window.getSize().x/2.f, window.getSize().y/2.f},
			{window.getSize().x/2.f, window.getSize().y/2.f}
		}}
	);

	quadtree->max_depth = 50;
	quadtree->max_elements_before_split = 5;
	quadtree->adjacent = false;

	wind::Engine engine;
	engine.gravity = false;

	engine.set_integrator(wind::Integrators::RK4);

	bool render_partitioning=true;
	engine.use_spatial_partitioning = true;
	engine.set_partition_method(std::static_pointer_cast<wind::Partition>(grid));

	// Create array of physics objects
	wind::Vector2u amount{100, 100};
	std::vector<std::shared_ptr<wind::Entity>> particles;
	particles.resize(amount.x*amount.y);
	std::cout<<"num_particles: "<<particles.size()<<std::endl;

	// Create particle shapes and bodies
	std::shared_ptr<wind::Body> particle_body=std::make_shared<wind::Body>();
	//std::shared_ptr<wind::Shape> particle_shape=std::make_shared<wind::CircleShape>(0.75f);
	std::shared_ptr<wind::Shape> particle_shape=std::make_shared<wind::RectangleShape>(wind::AABB{{0,0},{0.75f,0.75f}});
	particle_body->add_shape(particle_shape);

	// Assign particle positions
	for(auto particle_index=0; particle_index < particles.size(); ++particle_index)
	{
		auto& particle = particles[particle_index];
		particle = std::make_shared<wind::Entity>();

		particle->position.x = particle_index%amount.y+1;
		particle->position.y = particle_index/amount.x+1;
		particle->position.x*= window.getSize().x/(amount.x+1);
		particle->position.y*= window.getSize().y/(amount.y+1);
		particle->mass = 10000.f;//*(particle_index+1);
		particle->gravity_exert=true;
		particle->gravity_affected=true;
		particle->velocity = (wind::Vector2f{window.getSize().x/2.f, window.getSize().y/2.f}-particle->position)/1000.f;

		particle->set_body(particle_body);

		engine.add_entity(particle);
	}

	float step_time = 1.f;

	// Used for calculating frametimes
	auto frame_start = std::chrono::high_resolution_clock::now();
	while(window.isOpen())
	{
		auto frame_duration = std::chrono::high_resolution_clock::now() - frame_start;
		frame_start = std::chrono::high_resolution_clock::now();

		auto frame_duration_us = std::chrono::duration_cast<std::chrono::microseconds>(frame_duration);
		auto frametime_us = frame_duration_us.count();
		auto frametime_ms = frametime_us/1000.f;
		auto frametime_s  = frametime_ms/1000.f;

		window.setTitle(
			"Windtunnel :: [FPS] " + std::to_string(1.f/(frametime_s)) +
			"\t:: [Frametime] " + std::to_string(frametime_us) + "us" +
			"\t:: [Steptime] " + std::to_string(step_time) + "s"
		);

		sf::Event event;
		while(window.pollEvent(event))
		{
			switch(event.type)
			{
			case sf::Event::Closed:
				window.close();
				break;
			case sf::Event::KeyReleased:
				switch(event.key.code)
				{
				case sf::Keyboard::G:
					engine.gravity = !engine.gravity;
					break;
				case sf::Keyboard::P:
					engine.use_spatial_partitioning = !engine.use_spatial_partitioning;
					break;
				case sf::Keyboard::Q:
					use_grid = !use_grid;
					if(use_grid)
					{
						quadtree->clear();
						engine.set_partition_method(std::static_pointer_cast<wind::Partition>(grid));
					}
					else
					{
						grid->clear();
						engine.set_partition_method(std::static_pointer_cast<wind::Partition>(quadtree));
					}
					break;
				case sf::Keyboard::R:
					render_partitioning = !render_partitioning;
					break;
				case sf::Keyboard::Dash:
					step_time /= 2.f;
					break;
				case sf::Keyboard::Equal:
					step_time *= 2.f;
					break;
				default:
					break;
				}
			default:
				break;
			}
		}

		window.clear(sf::Color::Black);

		engine.simulate(wind::Engine::StandardDuration(step_time));

		if(render_partitioning)
		{
			if(use_grid)
				draw_grid(window, grid.get());
			else
				draw_quadtree(window, quadtree.get());
		}

		for(auto& particle : particles)
		{
			particle_drawable.setPosition(particle->position.x, particle->position.y);
			window.draw(particle_drawable);
		}
		window.display();

	}
}

void draw_quadtree(sf::RenderWindow &window, const wind::QuadTree *tree)
{
	if(tree->get_nodes()!=nullptr)
	{
		draw_quadtree(window, &(tree->get_nodes()[0]));
		draw_quadtree(window, &(tree->get_nodes()[1]));
		draw_quadtree(window, &(tree->get_nodes()[2]));
		draw_quadtree(window, &(tree->get_nodes()[3]));
	}
	else
	{
		sf::RectangleShape shape;
		shape.setFillColor({0,0,0,0});
		if(tree->get_entities().empty())
		{
			shape.setOutlineColor({255,0,0, 127});
			shape.setOutlineThickness(2);
		}
		else
		{
			shape.setOutlineColor({0,255,0, 127});
			shape.setOutlineThickness(2);
		}
		shape.setPosition({tree->get_bounds().center.x-tree->get_bounds().half_size.x+2.f, tree->get_bounds().center.y-tree->get_bounds().half_size.y+2.f});
		shape.setSize({tree->get_bounds().half_size.x*2.f-2.f,tree->get_bounds().half_size.y*2.f-2.f});
		window.draw(shape);
	}
}

void draw_grid(sf::RenderWindow &window, const wind::Grid *grid)
{
	const auto& entities = grid->get_entity_vector();

	for(int x=0; x < entities.size(); ++x)
	{
		for(int y=0; y < entities[x].size(); ++y)
		{
			sf::RectangleShape shape;
			shape.setFillColor({0,0,0,0});
			shape.setOutlineThickness(2);
			if(entities[x][y].empty())
			{
				shape.setOutlineColor({255,0,0,127});
			}
			else
			{
				shape.setOutlineColor({0,255,0,127});
			}
			auto pos = grid->get_bounds().center-grid->get_bounds().half_size+(static_cast<wind::Vector2f>(grid->node_size)*wind::Vector2f{static_cast<float>(x),static_cast<float>(y)});
			shape.setPosition(pos.x, pos.y);
			shape.setSize({static_cast<float>(grid->node_size.x), static_cast<float>(grid->node_size.y)});
			window.draw(shape);
		}
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/globals.h"
#if defined(TARGET_OS_WINDOWS)

#include "vm/os.h"

#include <malloc.h>  // NOLINT
#include <process.h>  // NOLINT
#include <time.h>  // NOLINT

#include "platform/utils.h"
#include "platform/assert.h"
#include "vm/os_thread.h"
#include "vm/vtune.h"
#include "vm/zone.h"

namespace dart {

const char* OS::Name() {
  return "windows";
}

intptr_t OS::ProcessId() {
  return static_cast<intptr_t>(GetCurrentProcessId());
}

// As a side-effect sets the globals _timezone, _daylight and _tzname.
static bool LocalTime(int64_t seconds_since_epoch, tm* tm_result) {
  time_t seconds = static_cast<time_t>(seconds_since_epoch);
  if (seconds != seconds_since_epoch) return false;
  // localtime_s implicitly sets _timezone, _daylight and _tzname.
  errno_t error_code = localtime_s(tm_result, &seconds);
  return error_code == 0;
}

static int GetDaylightSavingBiasInSeconds() {
  TIME_ZONE_INFORMATION zone_information;
  memset(&zone_information, 0, sizeof(zone_information));
  if (GetTimeZoneInformation(&zone_information) == TIME_ZONE_ID_INVALID) {
    // By default the daylight saving offset is an hour.
    return -60 * 60;
  } else {
    return static_cast<int>(zone_information.DaylightBias * 60);
  }
}

const char* OS::GetTimeZoneName(int64_t seconds_since_epoch) {
  tm decomposed;
  // LocalTime will set _tzname.
  bool succeeded = LocalTime(seconds_since_epoch, &decomposed);
  if (succeeded) {
    int inDaylightSavingsTime = decomposed.tm_isdst;
    ASSERT(inDaylightSavingsTime == 0 || inDaylightSavingsTime == 1);
    return _tzname[inDaylightSavingsTime];
  } else {
    // Return an empty string like V8 does.
    return "";
  }
}

int OS::GetTimeZoneOffsetInSeconds(int64_t seconds_since_epoch) {
  tm decomposed;
  // LocalTime will set _timezone.
  bool succeeded = LocalTime(seconds_since_epoch, &decomposed);
  if (succeeded) {
    int inDaylightSavingsTime = decomposed.tm_isdst;
    ASSERT(inDaylightSavingsTime == 0 || inDaylightSavingsTime == 1);
    // Dart and Windows disagree on the sign of the bias.
    int offset = static_cast<int>(-_timezone);
    if (inDaylightSavingsTime == 1) {
      static int daylight_bias = GetDaylightSavingBiasInSeconds();
      // Subtract because windows and Dart disagree on the sign.
      offset = offset - daylight_bias;
    }
    return offset;
  } else {
    // Return zero like V8 does.
    return 0;
  }
}

int OS::GetLocalTimeZoneAdjustmentInSeconds() {
  // TODO(floitsch): avoid excessive calls to _tzset?
  _tzset();
  // Dart and Windows disagree on the sign of the bias.
  return static_cast<int>(-_timezone);
}

int64_t OS::GetCurrentTimeMillis() {
  return GetCurrentTimeMicros() / 1000;
}

int64_t OS::GetCurrentTimeMicros() {
  static const int64_t kTimeEpoc = 116444736000000000LL;
  static const int64_t kTimeScaler = 10;  // 100 ns to us.

  // Although win32 uses 64-bit integers for representing timestamps,
  // these are packed into a FILETIME structure. The FILETIME
  // structure is just a struct representing a 64-bit integer. The
  // TimeStamp union allows access to both a FILETIME and an integer
  // representation of the timestamp. The Windows timestamp is in
  // 100-nanosecond intervals since January 1, 1601.
  union TimeStamp {
    FILETIME ft_;
    int64_t t_;
  };
  TimeStamp time;
  GetSystemTimeAsFileTime(&time.ft_);
  return (time.t_ - kTimeEpoc) / kTimeScaler;
}

static int64_t qpc_ticks_per_second = 0;

int64_t OS::GetCurrentMonotonicTicks() {
  if (qpc_ticks_per_second == 0) {
    // QueryPerformanceCounter not supported, fallback.
    return GetCurrentTimeMicros();
  }
  // Grab performance counter value.
  LARGE_INTEGER now;
  QueryPerformanceCounter(&now);
  int64_t qpc_value = static_cast<int64_t>(now.QuadPart);
}

int64_t OS::GetCurrentMonotonicFrequency() {
  if (qpc_ticks_per_second == 0) {
    // QueryPerformanceCounter not supported, fallback.
    return kMicrosecondsPerSecond;
  }
  return qpc_ticks_per_second;
}

int64_t OS::GetCurrentMonotonicMicros() {
  int64_t ticks = GetCurrentMonotonicTicks();
  int64_t frequency = GetCurrentMonotonicFrequency();

  // Convert to microseconds.
  int64_t seconds = ticks / frequency;
  int64_t leftover_ticks = ticks - (seconds * frequency);
  int64_t result = seconds * kMicrosecondsPerSecond;
  result += ((leftover_ticks * kMicrosecondsPerSecond) / frequency);
  return result;
}

void* OS::AlignedAllocate(intptr_t size, intptr_t alignment) {
  const int kMinimumAlignment = 16;
  ASSERT(Utils::IsPowerOfTwo(alignment));
  ASSERT(alignment >= kMinimumAlignment);
  void* p = _aligned_malloc(size, alignment);
  if (p == NULL) {
    UNREACHABLE();
  }
  return p;
}

void OS::AlignedFree(void* ptr) {
  _aligned_free(ptr);
}

intptr_t OS::ActivationFrameAlignment() {
#ifdef _WIN64
  // Windows 64-bit ABI requires the stack to be 16-byte aligned.
  return 16;
#else
  // No requirements on Win32.
  return 1;
#endif
}

intptr_t OS::PreferredCodeAlignment() {
  ASSERT(32 <= OS::kMaxPreferredCodeAlignment);
  return 32;
}

bool OS::AllowStackFrameIteratorFromAnotherThread() {
  return true;
}

int OS::NumberOfAvailableProcessors() {
  SYSTEM_INFO info;
  GetSystemInfo(&info);
  return info.dwNumberOfProcessors;
}

void OS::Sleep(int64_t millis) {
  ::Sleep(millis);
}

void OS::SleepMicros(int64_t micros) {
  // Windows only supports millisecond sleeps.
  if (micros < kMicrosecondsPerMillisecond) {
    // Calling ::Sleep with 0 has no determined behaviour, round up.
    micros = kMicrosecondsPerMillisecond;
  }
  OS::Sleep(micros / kMicrosecondsPerMillisecond);
}

void OS::DebugBreak() {
#if defined(_MSC_VER)
  // Microsoft Visual C/C++ or drop-in replacement.
  __debugbreak();
#elif defined(__GCC__)
  __builtin_trap();
#else
  // Microsoft style assembly.
  __asm {
    int 3
  }
#endif
}

char* OS::StrNDup(const char* s, intptr_t n) {
  intptr_t len = strlen(s);
  if ((n < 0) || (len < 0)) {
    return NULL;
  }
  if (n < len) {
    len = n;
  }
  char* result = reinterpret_cast<char*>(malloc(len + 1));
  if (result == NULL) {
    return NULL;
  }
  result[len] = '\0';
  return reinterpret_cast<char*>(memmove(result, s, len));
}

void OS::Print(const char* format, ...) {
  va_list args;
  va_start(args, format);
  VFPrint(stdout, format, args);
  va_end(args);
}

void OS::VFPrint(FILE* stream, const char* format, va_list args) {
  vfprintf(stream, format, args);
  fflush(stream);
}

int OS::SNPrint(char* str, size_t size, const char* format, ...) {
  va_list args;
  va_start(args, format);
  int retval = VSNPrint(str, size, format, args);
  va_end(args);
  return retval;
}

int OS::VSNPrint(char* str, size_t size, const char* format, va_list args) {
  if (str == NULL || size == 0) {
    int retval = _vscprintf(format, args);
    if (retval < 0) {
      FATAL1("Fatal error in OS::VSNPrint with format '%s'", format);
    }
    return retval;
  }
  va_list args_copy;
  va_copy(args_copy, args);
  int written = _vsnprintf(str, size, format, args_copy);
  va_end(args_copy);
  if (written < 0) {
    // _vsnprintf returns -1 if the number of characters to be written is
    // larger than 'size', so we call _vscprintf which returns the number
    // of characters that would have been written.
    va_list args_retry;
    va_copy(args_retry, args);
    written = _vscprintf(format, args_retry);
    if (written < 0) {
      FATAL1("Fatal error in OS::VSNPrint with format '%s'", format);
    }
    va_end(args_retry);
  }
  // Make sure to zero-terminate the string if the output was
  // truncated or if there was an error.
  // The static cast is safe here as we have already determined that 'written'
  // is >= 0.
  if (static_cast<size_t>(written) >= size) {
    str[size - 1] = '\0';
  }
  return written;
}

char* OS::SCreate(Zone* zone, const char* format, ...) {
  va_list args;
  va_start(args, format);
  char* buffer = VSCreate(zone, format, args);
  va_end(args);
  return buffer;
}

char* OS::VSCreate(Zone* zone, const char* format, va_list args) {
  // Measure.
  va_list measure_args;
  va_copy(measure_args, args);
  intptr_t len = VSNPrint(NULL, 0, format, measure_args);
  va_end(measure_args);

  char* buffer;
  if (zone) {
    buffer = zone->Alloc<char>(len + 1);
  } else {
    buffer = reinterpret_cast<char*>(malloc(len + 1));
  }
  ASSERT(buffer != NULL);

  // Print.
  va_list print_args;
  va_copy(print_args, args);
  VSNPrint(buffer, len + 1, format, print_args);
  va_end(print_args);
  return buffer;
}

bool OS::StringToInt64(const char* str, int64_t* value) {
  ASSERT(str != NULL && strlen(str) > 0 && value != NULL);
  int32_t base = 10;
  char* endptr;
  int i = 0;
  if (str[0] == '-') {
    i = 1;
  }
  if ((str[i] == '0') &&
      (str[i + 1] == 'x' || str[i + 1] == 'X') &&
      (str[i + 2] != '\0')) {
    base = 16;
  }
  errno = 0;
  *value = _strtoi64(str, &endptr, base);
  return ((errno == 0) && (endptr != str) && (*endptr == 0));
}

void OS::RegisterCodeObservers() {
#if defined(DART_VTUNE_SUPPORT)
  CodeObservers::Register(new VTuneCodeObserver);
#endif
}

void OS::PrintErr(const char* format, ...) {
  va_list args;
  va_start(args, format);
  VFPrint(stderr, format, args);
  va_end(args);
}

void OS::InitOnce() {
  // TODO(5411554): For now we check that initonce is called only once,
  // Once there is more formal mechanism to call InitOnce we can move
  // this check there.
  static bool init_once_called = false;
  ASSERT(init_once_called == false);
  init_once_called = true;
  // Do not pop up a message box when abort is called.
  _set_abort_behavior(0, _WRITE_ABORT_MSG);
  ThreadLocalData::InitOnce();
  MonitorWaitData::monitor_wait_data_key_ = OSThread::CreateThreadLocal();
  MonitorData::GetMonitorWaitDataForThread();
  LARGE_INTEGER ticks_per_sec;
  if (!QueryPerformanceFrequency(&ticks_per_sec)) {
    qpc_ticks_per_second = 0;
  } else {
    qpc_ticks_per_second = static_cast<int64_t>(ticks_per_sec.QuadPart);
  }
}

void OS::Shutdown() {
  // TODO(zra): Enable once VM can shutdown cleanly.
  // ThreadLocalData::Shutdown();
}

void OS::Abort() {
  abort();
}

void OS::Exit(int code) {
  exit(code);
}

}  // namespace dart

#endif  // defined(TARGET_OS_WINDOWS)
<commit_msg>Add missing return statement to fix Windows builds<commit_after>// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/globals.h"
#if defined(TARGET_OS_WINDOWS)

#include "vm/os.h"

#include <malloc.h>  // NOLINT
#include <process.h>  // NOLINT
#include <time.h>  // NOLINT

#include "platform/utils.h"
#include "platform/assert.h"
#include "vm/os_thread.h"
#include "vm/vtune.h"
#include "vm/zone.h"

namespace dart {

const char* OS::Name() {
  return "windows";
}

intptr_t OS::ProcessId() {
  return static_cast<intptr_t>(GetCurrentProcessId());
}

// As a side-effect sets the globals _timezone, _daylight and _tzname.
static bool LocalTime(int64_t seconds_since_epoch, tm* tm_result) {
  time_t seconds = static_cast<time_t>(seconds_since_epoch);
  if (seconds != seconds_since_epoch) return false;
  // localtime_s implicitly sets _timezone, _daylight and _tzname.
  errno_t error_code = localtime_s(tm_result, &seconds);
  return error_code == 0;
}

static int GetDaylightSavingBiasInSeconds() {
  TIME_ZONE_INFORMATION zone_information;
  memset(&zone_information, 0, sizeof(zone_information));
  if (GetTimeZoneInformation(&zone_information) == TIME_ZONE_ID_INVALID) {
    // By default the daylight saving offset is an hour.
    return -60 * 60;
  } else {
    return static_cast<int>(zone_information.DaylightBias * 60);
  }
}

const char* OS::GetTimeZoneName(int64_t seconds_since_epoch) {
  tm decomposed;
  // LocalTime will set _tzname.
  bool succeeded = LocalTime(seconds_since_epoch, &decomposed);
  if (succeeded) {
    int inDaylightSavingsTime = decomposed.tm_isdst;
    ASSERT(inDaylightSavingsTime == 0 || inDaylightSavingsTime == 1);
    return _tzname[inDaylightSavingsTime];
  } else {
    // Return an empty string like V8 does.
    return "";
  }
}

int OS::GetTimeZoneOffsetInSeconds(int64_t seconds_since_epoch) {
  tm decomposed;
  // LocalTime will set _timezone.
  bool succeeded = LocalTime(seconds_since_epoch, &decomposed);
  if (succeeded) {
    int inDaylightSavingsTime = decomposed.tm_isdst;
    ASSERT(inDaylightSavingsTime == 0 || inDaylightSavingsTime == 1);
    // Dart and Windows disagree on the sign of the bias.
    int offset = static_cast<int>(-_timezone);
    if (inDaylightSavingsTime == 1) {
      static int daylight_bias = GetDaylightSavingBiasInSeconds();
      // Subtract because windows and Dart disagree on the sign.
      offset = offset - daylight_bias;
    }
    return offset;
  } else {
    // Return zero like V8 does.
    return 0;
  }
}

int OS::GetLocalTimeZoneAdjustmentInSeconds() {
  // TODO(floitsch): avoid excessive calls to _tzset?
  _tzset();
  // Dart and Windows disagree on the sign of the bias.
  return static_cast<int>(-_timezone);
}

int64_t OS::GetCurrentTimeMillis() {
  return GetCurrentTimeMicros() / 1000;
}

int64_t OS::GetCurrentTimeMicros() {
  static const int64_t kTimeEpoc = 116444736000000000LL;
  static const int64_t kTimeScaler = 10;  // 100 ns to us.

  // Although win32 uses 64-bit integers for representing timestamps,
  // these are packed into a FILETIME structure. The FILETIME
  // structure is just a struct representing a 64-bit integer. The
  // TimeStamp union allows access to both a FILETIME and an integer
  // representation of the timestamp. The Windows timestamp is in
  // 100-nanosecond intervals since January 1, 1601.
  union TimeStamp {
    FILETIME ft_;
    int64_t t_;
  };
  TimeStamp time;
  GetSystemTimeAsFileTime(&time.ft_);
  return (time.t_ - kTimeEpoc) / kTimeScaler;
}

static int64_t qpc_ticks_per_second = 0;

int64_t OS::GetCurrentMonotonicTicks() {
  if (qpc_ticks_per_second == 0) {
    // QueryPerformanceCounter not supported, fallback.
    return GetCurrentTimeMicros();
  }
  // Grab performance counter value.
  LARGE_INTEGER now;
  QueryPerformanceCounter(&now);
  return static_cast<int64_t>(now.QuadPart);
}

int64_t OS::GetCurrentMonotonicFrequency() {
  if (qpc_ticks_per_second == 0) {
    // QueryPerformanceCounter not supported, fallback.
    return kMicrosecondsPerSecond;
  }
  return qpc_ticks_per_second;
}

int64_t OS::GetCurrentMonotonicMicros() {
  int64_t ticks = GetCurrentMonotonicTicks();
  int64_t frequency = GetCurrentMonotonicFrequency();

  // Convert to microseconds.
  int64_t seconds = ticks / frequency;
  int64_t leftover_ticks = ticks - (seconds * frequency);
  int64_t result = seconds * kMicrosecondsPerSecond;
  result += ((leftover_ticks * kMicrosecondsPerSecond) / frequency);
  return result;
}

void* OS::AlignedAllocate(intptr_t size, intptr_t alignment) {
  const int kMinimumAlignment = 16;
  ASSERT(Utils::IsPowerOfTwo(alignment));
  ASSERT(alignment >= kMinimumAlignment);
  void* p = _aligned_malloc(size, alignment);
  if (p == NULL) {
    UNREACHABLE();
  }
  return p;
}

void OS::AlignedFree(void* ptr) {
  _aligned_free(ptr);
}

intptr_t OS::ActivationFrameAlignment() {
#ifdef _WIN64
  // Windows 64-bit ABI requires the stack to be 16-byte aligned.
  return 16;
#else
  // No requirements on Win32.
  return 1;
#endif
}

intptr_t OS::PreferredCodeAlignment() {
  ASSERT(32 <= OS::kMaxPreferredCodeAlignment);
  return 32;
}

bool OS::AllowStackFrameIteratorFromAnotherThread() {
  return true;
}

int OS::NumberOfAvailableProcessors() {
  SYSTEM_INFO info;
  GetSystemInfo(&info);
  return info.dwNumberOfProcessors;
}

void OS::Sleep(int64_t millis) {
  ::Sleep(millis);
}

void OS::SleepMicros(int64_t micros) {
  // Windows only supports millisecond sleeps.
  if (micros < kMicrosecondsPerMillisecond) {
    // Calling ::Sleep with 0 has no determined behaviour, round up.
    micros = kMicrosecondsPerMillisecond;
  }
  OS::Sleep(micros / kMicrosecondsPerMillisecond);
}

void OS::DebugBreak() {
#if defined(_MSC_VER)
  // Microsoft Visual C/C++ or drop-in replacement.
  __debugbreak();
#elif defined(__GCC__)
  __builtin_trap();
#else
  // Microsoft style assembly.
  __asm {
    int 3
  }
#endif
}

char* OS::StrNDup(const char* s, intptr_t n) {
  intptr_t len = strlen(s);
  if ((n < 0) || (len < 0)) {
    return NULL;
  }
  if (n < len) {
    len = n;
  }
  char* result = reinterpret_cast<char*>(malloc(len + 1));
  if (result == NULL) {
    return NULL;
  }
  result[len] = '\0';
  return reinterpret_cast<char*>(memmove(result, s, len));
}

void OS::Print(const char* format, ...) {
  va_list args;
  va_start(args, format);
  VFPrint(stdout, format, args);
  va_end(args);
}

void OS::VFPrint(FILE* stream, const char* format, va_list args) {
  vfprintf(stream, format, args);
  fflush(stream);
}

int OS::SNPrint(char* str, size_t size, const char* format, ...) {
  va_list args;
  va_start(args, format);
  int retval = VSNPrint(str, size, format, args);
  va_end(args);
  return retval;
}

int OS::VSNPrint(char* str, size_t size, const char* format, va_list args) {
  if (str == NULL || size == 0) {
    int retval = _vscprintf(format, args);
    if (retval < 0) {
      FATAL1("Fatal error in OS::VSNPrint with format '%s'", format);
    }
    return retval;
  }
  va_list args_copy;
  va_copy(args_copy, args);
  int written = _vsnprintf(str, size, format, args_copy);
  va_end(args_copy);
  if (written < 0) {
    // _vsnprintf returns -1 if the number of characters to be written is
    // larger than 'size', so we call _vscprintf which returns the number
    // of characters that would have been written.
    va_list args_retry;
    va_copy(args_retry, args);
    written = _vscprintf(format, args_retry);
    if (written < 0) {
      FATAL1("Fatal error in OS::VSNPrint with format '%s'", format);
    }
    va_end(args_retry);
  }
  // Make sure to zero-terminate the string if the output was
  // truncated or if there was an error.
  // The static cast is safe here as we have already determined that 'written'
  // is >= 0.
  if (static_cast<size_t>(written) >= size) {
    str[size - 1] = '\0';
  }
  return written;
}

char* OS::SCreate(Zone* zone, const char* format, ...) {
  va_list args;
  va_start(args, format);
  char* buffer = VSCreate(zone, format, args);
  va_end(args);
  return buffer;
}

char* OS::VSCreate(Zone* zone, const char* format, va_list args) {
  // Measure.
  va_list measure_args;
  va_copy(measure_args, args);
  intptr_t len = VSNPrint(NULL, 0, format, measure_args);
  va_end(measure_args);

  char* buffer;
  if (zone) {
    buffer = zone->Alloc<char>(len + 1);
  } else {
    buffer = reinterpret_cast<char*>(malloc(len + 1));
  }
  ASSERT(buffer != NULL);

  // Print.
  va_list print_args;
  va_copy(print_args, args);
  VSNPrint(buffer, len + 1, format, print_args);
  va_end(print_args);
  return buffer;
}

bool OS::StringToInt64(const char* str, int64_t* value) {
  ASSERT(str != NULL && strlen(str) > 0 && value != NULL);
  int32_t base = 10;
  char* endptr;
  int i = 0;
  if (str[0] == '-') {
    i = 1;
  }
  if ((str[i] == '0') &&
      (str[i + 1] == 'x' || str[i + 1] == 'X') &&
      (str[i + 2] != '\0')) {
    base = 16;
  }
  errno = 0;
  *value = _strtoi64(str, &endptr, base);
  return ((errno == 0) && (endptr != str) && (*endptr == 0));
}

void OS::RegisterCodeObservers() {
#if defined(DART_VTUNE_SUPPORT)
  CodeObservers::Register(new VTuneCodeObserver);
#endif
}

void OS::PrintErr(const char* format, ...) {
  va_list args;
  va_start(args, format);
  VFPrint(stderr, format, args);
  va_end(args);
}

void OS::InitOnce() {
  // TODO(5411554): For now we check that initonce is called only once,
  // Once there is more formal mechanism to call InitOnce we can move
  // this check there.
  static bool init_once_called = false;
  ASSERT(init_once_called == false);
  init_once_called = true;
  // Do not pop up a message box when abort is called.
  _set_abort_behavior(0, _WRITE_ABORT_MSG);
  ThreadLocalData::InitOnce();
  MonitorWaitData::monitor_wait_data_key_ = OSThread::CreateThreadLocal();
  MonitorData::GetMonitorWaitDataForThread();
  LARGE_INTEGER ticks_per_sec;
  if (!QueryPerformanceFrequency(&ticks_per_sec)) {
    qpc_ticks_per_second = 0;
  } else {
    qpc_ticks_per_second = static_cast<int64_t>(ticks_per_sec.QuadPart);
  }
}

void OS::Shutdown() {
  // TODO(zra): Enable once VM can shutdown cleanly.
  // ThreadLocalData::Shutdown();
}

void OS::Abort() {
  abort();
}

void OS::Exit(int code) {
  exit(code);
}

}  // namespace dart

#endif  // defined(TARGET_OS_WINDOWS)
<|endoftext|>


<commit_before>/*
 * This example shows how to create ELF object file for Linux on x86
 *
 * Instructions:
 * 1. Compile and link this file with ELFIO library
 *    g++ write_obj.cpp -o writer_obj
 * 2. Execute result file write_obj
 *    ./write_obj
 * 3. Link output file hello.o:
 *    ld -m elf x64 -o hello hello.o
 * 4. Run the result file:
 *    ./hello
 */

#include <elfio/elfio.hpp>

using namespace ELFIO;

int main( void )
{
    elfio writer;

    // You can't proceed before this function call!
    writer.create( ELFCLASS64, ELFDATA2LSB );

    writer.set_os_abi( ELFOSABI_LINUX );
    writer.set_type( ET_REL );
    writer.set_machine(EM_X86_64);

    // This is our code
    char text[] = { '\xB8', '\x04', '\x00', '\x00', '\x00',   // mov eax, 4
                    '\xBB', '\x01', '\x00', '\x00', '\x00',   // mov ebx, 1
                    '\xB9', '\x00', '\x00', '\x00', '\x00',   // mov ecx, msg
                    '\xBA', '\x0E', '\x00', '\x00', '\x00',   // mov edx, 14
                    '\xCD', '\x80',                           // int 0x80
                    '\xB8', '\x01', '\x00', '\x00', '\x00',   // mov eax, 1
                    '\xCD', '\x80',                           // int 0x80
                    '\x48', '\x65', '\x6C', '\x6C', '\x6F',   // msg: db   'Hello, World!', 10
                    '\x2C', '\x20', '\x57', '\x6F', '\x72',
                    '\x6C', '\x64', '\x21', '\x0A'
                  };
    Elf64_Addr place_to_adjust = 11;

    // Create code section
    section* text_sec = writer.sections.add( ".text" );
    text_sec->set_type      ( SHT_PROGBITS );
    text_sec->set_flags     ( SHF_ALLOC | SHF_EXECINSTR );
    text_sec->set_addr_align( 0x10 );
    text_sec->set_data      ( text, sizeof( text ) );

    // Create string table section
    section* str_sec = writer.sections.add( ".strtab" );
    str_sec->set_type      ( SHT_STRTAB );

    // Create string table writer
    string_section_accessor stra( str_sec );
    // Add label name
    Elf32_Word str_index = stra.add_string( "msg" );

    // Create symbol table section
    section* sym_sec = writer.sections.add( ".symtab" );
    sym_sec->set_type      ( SHT_SYMTAB );
    sym_sec->set_info      ( 2 );
    sym_sec->set_addr_align( 0x4 );
    sym_sec->set_entry_size( writer.get_default_entry_size( SHT_SYMTAB ) );
    sym_sec->set_link      ( str_sec->get_index() );

    // Create symbol table writer
    symbol_section_accessor syma( writer, sym_sec );
    // Add symbol entry (msg has offset == 29)
    Elf_Word sym_to_adjust = syma.add_symbol( str_index, 29, 0, STB_GLOBAL,
                                              STT_OBJECT, 0,
                                              text_sec->get_index() );
    // Another way to add symbol
    syma.add_symbol( stra, "_start", 0x00000000, 0, STB_WEAK, STT_FUNC, 0,
                     text_sec->get_index() );

    // Create relocation table section
    section* rel_sec = writer.sections.add( ".rel.text" );
    rel_sec->set_type      ( SHT_REL );
    rel_sec->set_info      ( text_sec->get_index() );
    rel_sec->set_addr_align( 0x4 );
    rel_sec->set_entry_size( writer.get_default_entry_size( SHT_REL ) );
    rel_sec->set_link      ( sym_sec->get_index() );

    // Create relocation table writer
    relocation_section_accessor rela( writer, rel_sec );
    // Add relocation entry (adjust address at offset 11)
    rela.add_entry( place_to_adjust, sym_to_adjust,
                    (unsigned char)R_386_RELATIVE );

    // Another method to add the same relocation entry at one step is:
    // rela.add_entry( stra, "msg",
    //                 syma, 29, 0,
    //                 ELF_ST_INFO( STB_GLOBAL, STT_OBJECT ), 0,
    //                 text_sec->get_index(),
    //                 place_to_adjust, (unsigned char)R_386_RELATIVE );

    // Create note section
    section* note_sec = writer.sections.add( ".note" );
    note_sec->set_type( SHT_NOTE );

    note_section_accessor note_writer( writer, note_sec );
    note_writer.add_note( 0x01, "Created by ELFIO", 0, 0 );
    char descr[6] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36};
    note_writer.add_note( 0x01, "Never easier!", descr, sizeof( descr ) );

    // Create ELF object file
    writer.save( "hello.o" );

    return 0;
}
<commit_msg>Fix usage instructions; Symbol section info - reduced<commit_after>/*
 * This example shows how to create ELF object file for Linux on x86
 *
 * Instructions:
 * 1. Compile and link this file with ELFIO library
 *    g++ write_obj.cpp -o writer_obj
 * 2. Execute result file write_obj
 *    ./write_obj
 * 3. Link output file hello.o:
 *    ld -o hello hello.o
 * 4. Run the result file:
 *    ./hello
 */

#include <elfio/elfio.hpp>

using namespace ELFIO;

int main( void )
{
    elfio writer;

    // You can't proceed before this function call!
    writer.create( ELFCLASS64, ELFDATA2LSB );

    writer.set_os_abi( ELFOSABI_LINUX );
    writer.set_type( ET_REL );
    writer.set_machine(EM_X86_64);

    // This is our code
    char text[] = { '\xB8', '\x04', '\x00', '\x00', '\x00',   // mov eax, 4
                    '\xBB', '\x01', '\x00', '\x00', '\x00',   // mov ebx, 1
                    '\xB9', '\x00', '\x00', '\x00', '\x00',   // mov ecx, msg
                    '\xBA', '\x0E', '\x00', '\x00', '\x00',   // mov edx, 14
                    '\xCD', '\x80',                           // int 0x80
                    '\xB8', '\x01', '\x00', '\x00', '\x00',   // mov eax, 1
                    '\xCD', '\x80',                           // int 0x80
                    '\x48', '\x65', '\x6C', '\x6C', '\x6F',   // msg: db   'Hello, World!', 10
                    '\x2C', '\x20', '\x57', '\x6F', '\x72',
                    '\x6C', '\x64', '\x21', '\x0A'
                  };
    Elf64_Addr place_to_adjust = 11;

    // Create code section
    section* text_sec = writer.sections.add( ".text" );
    text_sec->set_type      ( SHT_PROGBITS );
    text_sec->set_flags     ( SHF_ALLOC | SHF_EXECINSTR );
    text_sec->set_addr_align( 0x10 );
    text_sec->set_data      ( text, sizeof( text ) );

    // Create string table section
    section* str_sec = writer.sections.add( ".strtab" );
    str_sec->set_type      ( SHT_STRTAB );

    // Create string table writer
    string_section_accessor stra( str_sec );
    // Add label name
    Elf32_Word str_index = stra.add_string( "msg" );

    // Create symbol table section
    section* sym_sec = writer.sections.add( ".symtab" );
    sym_sec->set_type      ( SHT_SYMTAB );
    sym_sec->set_info      ( 1 );
    sym_sec->set_addr_align( 0x4 );
    sym_sec->set_entry_size( writer.get_default_entry_size( SHT_SYMTAB ) );
    sym_sec->set_link      ( str_sec->get_index() );

    // Create symbol table writer
    symbol_section_accessor syma( writer, sym_sec );
    // Add symbol entry (msg has offset == 29)
    Elf_Word sym_to_adjust = syma.add_symbol( str_index, 29, 0, STB_GLOBAL,
                                              STT_OBJECT, 0,
                                              text_sec->get_index() );
    // Another way to add symbol
    syma.add_symbol( stra, "_start", 0x00000000, 0, STB_WEAK, STT_FUNC, 0,
                     text_sec->get_index() );

    // Create relocation table section
    section* rel_sec = writer.sections.add( ".rel.text" );
    rel_sec->set_type      ( SHT_REL );
    rel_sec->set_info      ( text_sec->get_index() );
    rel_sec->set_addr_align( 0x4 );
    rel_sec->set_entry_size( writer.get_default_entry_size( SHT_REL ) );
    rel_sec->set_link      ( sym_sec->get_index() );

    // Create relocation table writer
    relocation_section_accessor rela( writer, rel_sec );
    // Add relocation entry (adjust address at offset 11)
    rela.add_entry( place_to_adjust, sym_to_adjust,
                    (unsigned char)R_386_RELATIVE );

    // Another method to add the same relocation entry at one step is:
    // rela.add_entry( stra, "msg",
    //                 syma, 29, 0,
    //                 ELF_ST_INFO( STB_GLOBAL, STT_OBJECT ), 0,
    //                 text_sec->get_index(),
    //                 place_to_adjust, (unsigned char)R_386_RELATIVE );

    // Create note section
    section* note_sec = writer.sections.add( ".note" );
    note_sec->set_type( SHT_NOTE );

    note_section_accessor note_writer( writer, note_sec );
    note_writer.add_note( 0x01, "Created by ELFIO", 0, 0 );
    char descr[6] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36};
    note_writer.add_note( 0x01, "Never easier!", descr, sizeof( descr ) );

    // Create ELF object file
    writer.save( "hello.o" );

    return 0;
}
<|endoftext|>


<commit_before>
#include "../../headers/traitement/pathfinding.h"
#include "../../headers/manager.h"
#include "../../headers/definition.h"
#include <utility>
#include <vector>

using namespace std;

/*
vector<pair<int, int>> PathFinding::find(){
    return NULL;
}*/

/*http://www.robot-maker.com/forum/tutorials/article/35-exploration-pathfinding-dans-un-labyrinthe/*/

int PathFinding::test_case(int width, int height, int **tab, int x, int y){
    if(x>=0 && y>=0 && x<width && y<height && tab[x][y] == 0)
        return 1;
    return 0;
}

bool PathFinding::arround(int value, int search, int x, int y, int width, int height){
    if(x >= 0 && y >= 0 && x < width && y < height){
        return value == search;
    }
    return false;
}

int PathFinding::remplissage(int width, int height, int **tab, int nb_points, int *listX, int *listY,int Bx, int By){
    int *new_listX = (int*)malloc(sizeof(int)*nb_points*4);
    int *new_listY = (int*)malloc(sizeof(int)*nb_points*4);
    int new_nb_points=0;
    int i;
    bool toContinue;
    for(i=0;i<nb_points;i++)
    {
        toContinue = false;
        if(test_case(width,height,tab,listX[i]+1,listY[i]))
        {
            new_listX[new_nb_points] = listX[i]+1;
            new_listY[new_nb_points] = listY[i];
            tab[new_listX[new_nb_points]][new_listY[new_nb_points]] = tab[listX[i]][listY[i]] + 1;
            new_nb_points++;
            toContinue = true;
        }
        if(test_case(width,height,tab,listX[i]-1,listY[i]))
        {
            new_listX[new_nb_points] = listX[i]-1;
            new_listY[new_nb_points] = listY[i];
            tab[new_listX[new_nb_points]][new_listY[new_nb_points]] = tab[listX[i]][listY[i]] + 1;
            new_nb_points++;
            toContinue = true;
        }
        if(test_case(width,height,tab,listX[i],listY[i]+1))
        {
            new_listX[new_nb_points] = listX[i];
            new_listY[new_nb_points] = listY[i]+1;
            tab[new_listX[new_nb_points]][new_listY[new_nb_points]] = tab[listX[i]][listY[i]] + 1;
            new_nb_points++;
            toContinue = true;
        }
        if(test_case(width,height,tab,listX[i],listY[i]-1))
        {
            new_listX[new_nb_points] = listX[i];
            new_listY[new_nb_points] = listY[i]-1;
            tab[new_listX[new_nb_points]][new_listY[new_nb_points]] = tab[listX[i]][listY[i]] + 1;
            new_nb_points++;
            toContinue = true;
        }
    }
    free(listX);
    free(listY);
    if(new_listX[new_nb_points] > (width*height))
        return -1;
    if(tab[Bx][By]!=0){
        return 1;
    }
    else return remplissage(width, height, tab, new_nb_points, new_listX, new_listY,Bx, By);
}

std::vector<std::pair<int, int>> PathFinding::find()
{
    std::vector<std::pair<int, int>> coord;
    coord = vector<pair<int, int>>();
    if(Manager::getInstance()->getSceneCarrer() > 0){
        int Ax = Manager::getInstance()->car->getPosition().first;
        int Ay = Manager::getInstance()->car->getPosition().second;
        int Bx = Manager::getInstance()->arrive->getPosition().first;
        int By = Manager::getInstance()->arrive->getPosition().second;
        int i,j;
        int width = Manager::getInstance()->getSceneCarrer();
        int height = width;
        int **tab = (int**)malloc(width * sizeof(*tab));
        if(tab == NULL){
            std::cout << "ERREUR ALLOC Manager TABLES" << std::endl;
            return coord;
        }
        for(int aa = 0; aa < width; ++aa){
            tab[aa] = (int*)malloc(width * sizeof(**tab) );
            if(tab[aa] == NULL){
                for(int a=0 ; a < width ; a++){
                     free(tab[a]);
                }
            }
        }
        for(int xx=0; xx<width; ++xx){
            for(int yy=0; yy<height; ++yy){
                tab[xx][yy] = Manager::getInstance()->getCoordonate(xx, yy);
            }
        }
        tab[Bx][By] = 0;
        int *listX = (int*)malloc(sizeof(int)*1);
        int *listY = (int*)malloc(sizeof(int)*1);
        listX[0] = Ax;
        listY[0] = Ay;
        tab[Ax][Ay] = 1;
        int check = remplissage(width, height, tab, 1, listX, listY,Bx,By);
        if(check == -1)
            return coord;
        coord.push_back(make_pair(Bx, By));
        int index = tab[Bx][By];
        int indexX = Bx;
        int indexY = By;
        bool hasPosibility;
        while(true){
            hasPosibility = false;
            if(indexY-1 >=0){
                if(arround(tab[indexX][indexY-1], index - 1, indexX, indexY-1, width, height)){
                    coord.push_back(make_pair(indexX, indexY-1));
                    --indexY;
                    --index;
                    hasPosibility = true;
                }
            }
            if(indexX-1 >=0){
                if(arround(tab[indexX-1][indexY], index - 1, indexX-1, indexY, width, height)){
                    coord.push_back(make_pair(indexX-1, indexY));
                    --indexX;
                    --index;
                    hasPosibility = true;
                }
            }
            if(indexY+1 <height){
                if(arround(tab[indexX][indexY+1], index - 1, indexX, indexY+1, width, height)){
                    coord.push_back(make_pair(indexX, indexY+1));
                    ++indexY;
                    --index;
                    hasPosibility = true;
                }
            }
            if(indexX+1 < width){
                if(arround(tab[indexX+1][indexY], index - 1, indexX+1, indexY, width, height)){
                    coord.push_back(make_pair(indexX+1, indexY));
                    ++indexX;
                    --index;
                    hasPosibility = true;
                }
            }
            if(!hasPosibility){
                coord.clear();
                return coord;
            }
            if(index == 1){
                break;
            }
        }
        if(hasPosibility){
            for(int xx=0; xx<width; ++xx){
                free(tab[xx]);
            }
            free(tab);
        }else{
            coord.clear();
        }
        return coord;
    }else{
        return coord;
    }
}<commit_msg>Add possibity to have 100x100 matrice<commit_after>
#include "../../headers/traitement/pathfinding.h"
#include "../../headers/manager.h"
#include "../../headers/definition.h"
#include <utility>
#include <vector>
#include <algorithm>

using namespace std;

/*
vector<pair<int, int>> PathFinding::find(){
    return NULL;
}*/

/*http://www.robot-maker.com/forum/tutorials/article/35-exploration-pathfinding-dans-un-labyrinthe/*/

int PathFinding::test_case(int width, int height, int **tab, int x, int y){
    if(x>=0 && y>=0 && x<width && y<height && tab[x][y] == 0)
        return 1;
    return 0;
}

bool PathFinding::arround(int value, int search, int x, int y, int width, int height){
    if(x >= 0 && y >= 0 && x < width && y < height){
        return value == search;
    }
    return false;
}

int PathFinding::remplissage(int width, int height, int **tab, int nb_points, int *listX, int *listY,int Bx, int By){
    int *new_listX = (int*)malloc(sizeof(int)*nb_points*4);
    int *new_listY = (int*)malloc(sizeof(int)*nb_points*4);
    int new_nb_points=0;
    for(int i=0;i<nb_points;i++)
    {
        if(test_case(width,height,tab,listX[i]+1,listY[i]))
        {
            new_listX[new_nb_points] = listX[i]+1;
            new_listY[new_nb_points] = listY[i];
            tab[new_listX[new_nb_points]][new_listY[new_nb_points]] = tab[listX[i]][listY[i]] + 1;
            new_nb_points++;
        }
        if(test_case(width,height,tab,listX[i]-1,listY[i]))
        {
            new_listX[new_nb_points] = listX[i]-1;
            new_listY[new_nb_points] = listY[i];
            tab[new_listX[new_nb_points]][new_listY[new_nb_points]] = tab[listX[i]][listY[i]] + 1;
            new_nb_points++;
        }
        if(test_case(width,height,tab,listX[i],listY[i]+1))
        {
            new_listX[new_nb_points] = listX[i];
            new_listY[new_nb_points] = listY[i]+1;
            tab[new_listX[new_nb_points]][new_listY[new_nb_points]] = tab[listX[i]][listY[i]] + 1;
            new_nb_points++;
        }
        if(test_case(width,height,tab,listX[i],listY[i]-1))
        {
            new_listX[new_nb_points] = listX[i];
            new_listY[new_nb_points] = listY[i]-1;
            tab[new_listX[new_nb_points]][new_listY[new_nb_points]] = tab[listX[i]][listY[i]] + 1;
            new_nb_points++;
        }
    }
    free(listX);
    free(listY);
    if(new_listX[new_nb_points] >= 35635)
        return -1;
    if(tab[Bx][By]!=0){
        return 1;
    }
    else return remplissage(width, height, tab, new_nb_points, new_listX, new_listY,Bx, By);
}

std::vector<std::pair<int, int>> PathFinding::find()
{
    std::vector<std::pair<int, int>> coord;
    coord = vector<pair<int, int>>();
    if(Manager::getInstance()->getSceneCarrer() > 0){
        int Ax = Manager::getInstance()->car->getPosition().first;
        int Ay = Manager::getInstance()->car->getPosition().second;
        int Bx = Manager::getInstance()->arrive->getPosition().first;
        int By = Manager::getInstance()->arrive->getPosition().second;
        int i,j;
        int width = Manager::getInstance()->getSceneCarrer();
        int height = width;
        int **tab = (int**)malloc(width * sizeof(*tab));
        if(tab == NULL){
            std::cout << "ERREUR ALLOC Manager TABLES" << std::endl;
            return coord;
        }
        for(int aa = 0; aa < width; ++aa){
            tab[aa] = (int*)malloc(width * sizeof(**tab) );
            if(tab[aa] == NULL){
                for(int a=0 ; a < width ; a++){
                     free(tab[a]);
                }
            }
        }
        for(int xx=0; xx<width; ++xx){
            for(int yy=0; yy<height; ++yy){
                tab[xx][yy] = Manager::getInstance()->getCoordonate(xx, yy);
            }
        }
        tab[Bx][By] = 0;
        int *listX = (int*)malloc(sizeof(int)*1);
        int *listY = (int*)malloc(sizeof(int)*1);
        listX[0] = Ax;
        listY[0] = Ay;
        tab[Ax][Ay] = 1;
        int check = remplissage(width, height, tab, 1, listX, listY,Bx,By);
        if(check == -1)
            return coord;
        coord.push_back(make_pair(Bx, By));
        int index = tab[Bx][By];
        int indexX = Bx;
        int indexY = By;
        bool hasPosibility;
        while(true){
            hasPosibility = false;
            if(indexY-1 >=0){
                if(arround(tab[indexX][indexY-1], index - 1, indexX, indexY-1, width, height)){
                    coord.push_back(make_pair(indexX, indexY-1));
                    --indexY;
                    --index;
                    hasPosibility = true;
                }
            }
            if(indexX-1 >=0){
                if(arround(tab[indexX-1][indexY], index - 1, indexX-1, indexY, width, height)){
                    coord.push_back(make_pair(indexX-1, indexY));
                    --indexX;
                    --index;
                    hasPosibility = true;
                }
            }
            if(indexY+1 <height){
                if(arround(tab[indexX][indexY+1], index - 1, indexX, indexY+1, width, height)){
                    coord.push_back(make_pair(indexX, indexY+1));
                    ++indexY;
                    --index;
                    hasPosibility = true;
                }
            }
            if(indexX+1 < width){
                if(arround(tab[indexX+1][indexY], index - 1, indexX+1, indexY, width, height)){
                    coord.push_back(make_pair(indexX+1, indexY));
                    ++indexX;
                    --index;
                    hasPosibility = true;
                }
            }
            if(!hasPosibility){
                coord.clear();
                return coord;
            }
            if(index == 1){
                break;
            }
        }
        if(coord.size() > 1 || hasPosibility){
            for(int xx=0; xx<width; ++xx){
                free(tab[xx]);
            }
            free(tab);
        }else{
            coord.clear();
        }
        std::reverse(coord.begin(),coord.end()); //inverse le trajet (défaut: Arrivée -> Départ)
        return coord;
    }else{
        return coord;
    }
}<|endoftext|>


<commit_before>// Copyright 2011, Tokyo Institute of Technology.
// All rights reserved.
//
// This file is distributed under the license described in
// LICENSE.txt.
//
// Author: Naoya Maruyama (naoya@matsulab.is.titech.ac.jp)

#include "translator/optimizer/optimization_passes.h"
#include "translator/optimizer/optimization_common.h"
#include "translator/rose_util.h"
#include "translator/runtime_builder.h"
#include "translator/translation_util.h"

#include <algorithm>

namespace si = SageInterface;
namespace sb = SageBuilder;

namespace physis {
namespace translator {
namespace optimizer {
namespace pass {

// SageInterface has an function exactly for this purpose.
#if 0
static void RemoveUnusedLabel(SgProject *proj) {
  // Find used labels
  Rose_STL_Container<SgNode *> gotos =
      NodeQuery::querySubTree(proj, V_SgGotoStatement);
  std::vector<SgLabelStatement*> labels;
  FOREACH (it, gotos.begin(), gotos.end()) {
    SgGotoStatement *goto_stmt = isSgGotoStatement(*it);
    SgLabelStatement *label = goto_stmt->get_label();
    labels.push_back(label);
  }

  // Iterate over all labels and remove ones not included in the used
  // set.
  Rose_STL_Container<SgNode *> label_stmts =
      NodeQuery::querySubTree(proj, V_SgLabelStatement);
  FOREACH (it, label_stmts.begin(), label_stmts.end()) {
    SgLabelStatement *label = isSgLabelStatement(*it);
    if (isContained(labels, label)) continue;
    si::removeStatement(label);
  }
}
#endif

/*! Replace a variable reference in an offset expression.

  \param vref Variable reference
  \param loop_body Target loop
 */
static void replace_var_ref(SgVarRefExp *vref, SgBasicBlock *loop_body) {
  SgVariableDeclaration *vdecl = isSgVariableDeclaration(
      vref->get_symbol()->get_declaration()->get_declaration());
  vector<SgVariableDeclaration*> decls =
      si::querySubTree<SgVariableDeclaration>(loop_body, V_SgVariableDeclaration);
  if (!isContained(decls, vdecl)) return;
  if (!vdecl) return;
  SgAssignInitializer *init =
      isSgAssignInitializer(
          vdecl->get_definition()->get_vardefn()->get_initializer());
  if (!init) return;
  SgExpression *rhs = init->get_operand();
  LOG_DEBUG() << "RHS: " << rhs->unparseToString() << "\n";
  std::vector<SgVarRefExp*> vref_exprs =
      si::querySubTree<SgVarRefExp>(loop_body, V_SgVarRefExp);
  FOREACH (it, vref_exprs.begin(), vref_exprs.end()) {
    if (vdecl == isSgVariableDeclaration(
            (*it)->get_symbol()->get_declaration()->get_declaration())) {
      si::replaceExpression(*it, si::copyExpression(rhs));
    }
  }
  si::removeStatement(vdecl);
  return;
}

/*! Fix variable references in offset expression.

  Offset expressions may use a variable reference to grids and loop
  indices that are defined inside the target loop. They need to be
  replaced with their original value when moved out of the loop.

  \param offset_expr Offset expression
  \param loop_body Target loop body
*/
static void replace_arg_defined_in_loop(SgExpression *offset_expr,
                                        SgBasicBlock *loop_body) {
  LOG_DEBUG() << "Replacing undef var in "
              << offset_expr->unparseToString() << "\n";
  PSAssert(offset_expr != NULL && loop_body != NULL);
  SgFunctionCallExp *offset_call = isSgFunctionCallExp(offset_expr);
  PSAssert(offset_call);
  SgExpressionPtrList &args = offset_call->get_args()->get_expressions();
  //if (isSgVarRefExp(args[0])) {
  //replace_var_ref(isSgVarRefExp(args[0]), loop_body);
  //}
  FOREACH (argit, args.begin()+1, args.end()) {
    SgExpression *arg = *argit;
    Rose_STL_Container<SgNode*> vref_list =
        NodeQuery::querySubTree(arg, V_SgVarRefExp);
    if (vref_list.size() == 0) continue;
    PSAssert(vref_list.size() == 1);
    replace_var_ref(isSgVarRefExp(vref_list[0]), loop_body);
  }
  LOG_DEBUG() << "Replaced: " << offset_expr->unparseToString() << "\n";
  return;
}

static SgForStatement *FindInnermostMapLoop(SgFunctionCallExp *kernel_call) {
  for (SgNode *node = kernel_call->get_parent(); node != NULL;
       node = node->get_parent()) {
    RunKernelLoopAttribute *loop_attr
        = rose_util::GetASTAttribute<RunKernelLoopAttribute>(node);
    if (loop_attr) return isSgForStatement(node);
  }
  return NULL;
}

static void cleanup(SgFunctionCallExp *call_exp,
                    SgFunctionRefExp *callee_ref,
                    SgForStatement *loop) {
  std::vector<SgNode*> offset_exprs =
      rose_util::QuerySubTreeAttribute<GridOffsetAttribute>(
          loop);
  FOREACH (it, offset_exprs.begin(), offset_exprs.end()) {
    SgExpression *offset_expr = isSgExpression(*it);
    replace_arg_defined_in_loop(offset_expr,
                                isSgBasicBlock(loop->get_loop_body()));
  }
}

void kernel_inlining(
    SgProject *proj,
    physis::translator::TranslationContext *tx,
    physis::translator::RuntimeBuilder *builder) {
  pre_process(proj, tx, __FUNCTION__);

  //si::fixVariableReferences(proj);

  Rose_STL_Container<SgNode *> funcs =
      NodeQuery::querySubTree(proj, V_SgFunctionDeclaration);
  FOREACH(it, funcs.begin(), funcs.end()) {
    SgFunctionDeclaration *func = isSgFunctionDeclaration(*it);
    RunKernelAttribute *run_kernel_attr
        = rose_util::GetASTAttribute<RunKernelAttribute>(func);
    // Filter non RunKernel function
    if (!run_kernel_attr) continue;

    Rose_STL_Container<SgNode *> calls =
        NodeQuery::querySubTree(proj, V_SgFunctionCallExp);
    FOREACH (calls_it, calls.begin(), calls.end()) {
      SgFunctionCallExp *call_exp =
          isSgFunctionCallExp(*calls_it);
      SgFunctionRefExp *callee_ref
          = isSgFunctionRefExp(call_exp->get_function());
      if (!callee_ref) continue;
      SgFunctionDeclaration *callee_decl
          = rose_util::getFuncDeclFromFuncRef(callee_ref);
      if (!callee_decl) continue;
      if (!tx->isKernel(callee_decl)) continue;
      LOG_DEBUG() << "Inline a call to kernel found: "
                  << call_exp->unparseToString() << "\n";
      // Kernel call found
      SgForStatement *map_loop = FindInnermostMapLoop(call_exp);
      //SgNode *t = call_exp->get_parent();
      // while (t) {
      //   LOG_DEBUG() << "parent: ";
      //   LOG_DEBUG() << t->unparseToString() << "\n";
      //   t = t->get_parent();
      // }
      if (!doInline(call_exp)) {
        LOG_ERROR() << "Kernel inlining failed.\n";
        LOG_ERROR() << "Failed call: "
                    << call_exp->unparseToString() << "\n";
        PSAbort(1);
      }
      // Fix the grid attributes
      FixGridAttributes(proj);
      cleanup(call_exp, callee_ref, map_loop);
    }
  }

  // Remove unused lables created by doInline.
  //RemoveUnusedLabel(proj);
  si::removeUnusedLabels(proj);

  // Remove original kernels
  // NOTE: Does not work (segmentation fault) even if AST consistency is
  // kept.
  // cleanupInlinedCode(proj);

  post_process(proj, tx, __FUNCTION__);
}

} // namespace pass
} // namespace optimizer
} // namespace translator
} // namespace physis

<commit_msg>FIX: kernel inlining with red-black<commit_after>// Copyright 2011, Tokyo Institute of Technology.
// All rights reserved.
//
// This file is distributed under the license described in
// LICENSE.txt.
//
// Author: Naoya Maruyama (naoya@matsulab.is.titech.ac.jp)

#include "translator/optimizer/optimization_passes.h"
#include "translator/optimizer/optimization_common.h"
#include "translator/rose_util.h"
#include "translator/runtime_builder.h"
#include "translator/translation_util.h"

#include <algorithm>

namespace si = SageInterface;
namespace sb = SageBuilder;

namespace physis {
namespace translator {
namespace optimizer {
namespace pass {

// SageInterface has an function exactly for this purpose.
#if 0
static void RemoveUnusedLabel(SgProject *proj) {
  // Find used labels
  Rose_STL_Container<SgNode *> gotos =
      NodeQuery::querySubTree(proj, V_SgGotoStatement);
  std::vector<SgLabelStatement*> labels;
  FOREACH (it, gotos.begin(), gotos.end()) {
    SgGotoStatement *goto_stmt = isSgGotoStatement(*it);
    SgLabelStatement *label = goto_stmt->get_label();
    labels.push_back(label);
  }

  // Iterate over all labels and remove ones not included in the used
  // set.
  Rose_STL_Container<SgNode *> label_stmts =
      NodeQuery::querySubTree(proj, V_SgLabelStatement);
  FOREACH (it, label_stmts.begin(), label_stmts.end()) {
    SgLabelStatement *label = isSgLabelStatement(*it);
    if (isContained(labels, label)) continue;
    si::removeStatement(label);
  }
}
#endif

/*! Replace a variable reference in an offset expression.

  \param vref Variable reference
  \param loop_body Target loop
 */
static SgVarRefExp *replace_var_ref(SgVarRefExp *vref, SgBasicBlock *loop_body) {
  LOG_DEBUG() << "Replacing " << vref->unparseToString() << "\n";
  SgVariableDeclaration *vdecl = isSgVariableDeclaration(
      vref->get_symbol()->get_declaration()->get_declaration());
  vector<SgVariableDeclaration*> decls =
      si::querySubTree<SgVariableDeclaration>(loop_body, V_SgVariableDeclaration);
  if (!isContained(decls, vdecl)) return NULL;
  if (!vdecl) return NULL;
  SgAssignInitializer *init =
      isSgAssignInitializer(
          vdecl->get_definition()->get_vardefn()->get_initializer());
  if (!init) return NULL;
  SgExpression *rhs = init->get_operand();
  LOG_DEBUG() << "RHS: " << rhs->unparseToString() << "\n";
  PSAssert(isSgVarRefExp(rhs));
  std::vector<SgVarRefExp*> vref_exprs =
      si::querySubTree<SgVarRefExp>(loop_body, V_SgVarRefExp);
  FOREACH (it, vref_exprs.begin(), vref_exprs.end()) {
    if (vdecl == isSgVariableDeclaration(
            (*it)->get_symbol()->get_declaration()->get_declaration())) {
      si::replaceExpression(*it, si::copyExpression(rhs));
    }
  }
  si::removeStatement(vdecl);
  return isSgVarRefExp(rhs);
}

/*! Fix variable references in offset expression.

  Offset expressions may use a variable reference to grids and loop
  indices that are defined inside the target loop. They need to be
  replaced with their original value when moved out of the loop.

  \param offset_expr Offset expression
  \param loop_body Target loop body
*/
static void replace_arg_defined_in_loop(SgExpression *offset_expr,
                                        SgBasicBlock *loop_body,
                                        set<SgName> &original_names) {
  LOG_DEBUG() << "Replacing undef var in "
              << offset_expr->unparseToString() << "\n";
  PSAssert(offset_expr != NULL && loop_body != NULL);
  SgFunctionCallExp *offset_call = isSgFunctionCallExp(offset_expr);
  PSAssert(offset_call);
  SgExpressionPtrList &args = offset_call->get_args()->get_expressions();

  //if (isSgVarRefExp(args[0])) {
  //replace_var_ref(isSgVarRefExp(args[0]), loop_body);
  //}
  FOREACH (argit, args.begin()+1, args.end()) {
    SgExpression *arg = *argit;
    Rose_STL_Container<SgNode*> vref_list =
        NodeQuery::querySubTree(arg, V_SgVarRefExp);
    if (vref_list.size() == 0) continue;
    PSAssert(vref_list.size() == 1);
    if (isContained(
            original_names,
            rose_util::GetName(isSgVarRefExp(vref_list[0])))) {
      // Already replaced. This is a reference to a variable that is
      // defined in the loop instead of the kernel function.
      continue;
    }
    SgVarRefExp *vr = replace_var_ref(isSgVarRefExp(vref_list[0]), loop_body);
    if (vr) {
      LOG_DEBUG() << "Replaced with " << vr->unparseToString() << "\n";
      original_names.insert(rose_util::GetName(vr));
    }
  }
  LOG_DEBUG() << "Result: " << offset_expr->unparseToString() << "\n";
  return;
}

static SgForStatement *FindInnermostMapLoop(SgFunctionCallExp *kernel_call) {
  for (SgNode *node = kernel_call->get_parent(); node != NULL;
       node = node->get_parent()) {
    RunKernelLoopAttribute *loop_attr
        = rose_util::GetASTAttribute<RunKernelLoopAttribute>(node);
    if (loop_attr) return isSgForStatement(node);
  }
  return NULL;
}

static void cleanup(SgFunctionCallExp *call_exp,
                    SgFunctionRefExp *callee_ref,
                    SgForStatement *loop) {
  std::vector<SgNode*> offset_exprs =
      rose_util::QuerySubTreeAttribute<GridOffsetAttribute>(
          loop);
  set<SgName> original_names;
  FOREACH (it, offset_exprs.begin(), offset_exprs.end()) {
    SgExpression *offset_expr = isSgExpression(*it);
    replace_arg_defined_in_loop(offset_expr,
                                isSgBasicBlock(loop->get_loop_body()),
                                original_names);
  }
}

void kernel_inlining(
    SgProject *proj,
    physis::translator::TranslationContext *tx,
    physis::translator::RuntimeBuilder *builder) {
  pre_process(proj, tx, __FUNCTION__);

  //si::fixVariableReferences(proj);

  Rose_STL_Container<SgNode *> funcs =
      NodeQuery::querySubTree(proj, V_SgFunctionDeclaration);
  FOREACH(it, funcs.begin(), funcs.end()) {
    SgFunctionDeclaration *func = isSgFunctionDeclaration(*it);
    RunKernelAttribute *run_kernel_attr
        = rose_util::GetASTAttribute<RunKernelAttribute>(func);
    // Filter non RunKernel function
    if (!run_kernel_attr) continue;

    Rose_STL_Container<SgNode *> calls =
        NodeQuery::querySubTree(proj, V_SgFunctionCallExp);
    FOREACH (calls_it, calls.begin(), calls.end()) {
      SgFunctionCallExp *call_exp =
          isSgFunctionCallExp(*calls_it);
      SgFunctionRefExp *callee_ref
          = isSgFunctionRefExp(call_exp->get_function());
      if (!callee_ref) continue;
      SgFunctionDeclaration *callee_decl
          = rose_util::getFuncDeclFromFuncRef(callee_ref);
      if (!callee_decl) continue;
      if (!tx->isKernel(callee_decl)) continue;
      LOG_DEBUG() << "Inline a call to kernel found: "
                  << call_exp->unparseToString() << "\n";
      // Kernel call found
      SgForStatement *map_loop = FindInnermostMapLoop(call_exp);
      //SgNode *t = call_exp->get_parent();
      // while (t) {
      //   LOG_DEBUG() << "parent: ";
      //   LOG_DEBUG() << t->unparseToString() << "\n";
      //   t = t->get_parent();
      // }
      if (!doInline(call_exp)) {
        LOG_ERROR() << "Kernel inlining failed.\n";
        LOG_ERROR() << "Failed call: "
                    << call_exp->unparseToString() << "\n";
        PSAbort(1);
      }
      // Fix the grid attributes
      FixGridAttributes(proj);
      cleanup(call_exp, callee_ref, map_loop);
    }
  }

  // Remove unused lables created by doInline.
  //RemoveUnusedLabel(proj);
  si::removeUnusedLabels(proj);

  // Remove original kernels
  // NOTE: Does not work (segmentation fault) even if AST consistency is
  // kept.
  // cleanupInlinedCode(proj);

  post_process(proj, tx, __FUNCTION__);
}

} // namespace pass
} // namespace optimizer
} // namespace translator
} // namespace physis

<|endoftext|>