<commit_before>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2008 Scientific Computing and Imaging Institute,
   University of Utah.

   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.
*/

/**
  \file    TiffVolumeConverter.h
  \author  Tom Fogal
           SCI Institute
           University of Utah
*/
#include <cstring>
#ifndef TUVOK_NO_IO
# include "3rdParty/tiff/tiffio.h"
#else
  struct TIFF;
#endif
#include "TiffVolumeConverter.h"
#include "../StdTuvokDefines.h"
#include "../Controller/Controller.h"
#include "../Basics/SysTools.h"

#ifdef __GNUC__
# define _malloc __attribute__((malloc))
#else
# define _malloc /* nothing */
#endif

static void tv_dimensions(TIFF *, size_t dims[3]);
_malloc static BYTE* tv_read_slice(TIFF *);

TiffVolumeConverter::TiffVolumeConverter()
{
  m_vConverterDesc = "TIFF Volume (Image stack)";
#ifndef TUVOK_NO_IO
  m_vSupportedExt.push_back("OME.TIF");
  m_vSupportedExt.push_back("OME.TIFF");
  m_vSupportedExt.push_back("TIF");
  m_vSupportedExt.push_back("TIFF");
#endif
}

// converts a TiffVolume to a `raw' file.  We'll read through the TIFF
// slice-by-slice, copying each slice to the raw file.
bool
TiffVolumeConverter::ConvertToRAW(const std::string& strSourceFilename,
                                  const std::string& strTempDir,
                                  bool, uint64_t& iHeaderSkip,
                                  uint64_t& iComponentSize,
                                  uint64_t& iComponentCount,
                                  bool& bConvertEndianess, bool& bSigned,
                                  bool& bIsFloat, UINT64VECTOR3& vVolumeSize,
                                  FLOATVECTOR3& vVolumeAspect,
                                  std::string& strTitle,
                                  UVFTables::ElementSemanticTable& eType,
                                  std::string& strIntermediateFile,
                                  bool& bDeleteIntermediateFile)
{
#ifndef TUVOK_NO_IO
  MESSAGE("Attempting to convert TiffVolume: %s", strSourceFilename.c_str());

  TIFF *tif = TIFFOpen(strSourceFilename.c_str(), "r");
  if(tif == NULL) {
    T_ERROR("Could not open %s", strSourceFilename.c_str());
    return false;
  }

  // Get the dimensions of the volume.
  {
    size_t dims[3];
    tv_dimensions(tif, dims);
    vVolumeSize[0] = static_cast<uint64_t>(dims[0]);
    vVolumeSize[1] = static_cast<uint64_t>(dims[1]);
    vVolumeSize[2] = static_cast<uint64_t>(dims[2]);
    MESSAGE("TiffVolume dimensions: %ux%ux%u", static_cast<unsigned>(dims[0]),
                                               static_cast<unsigned>(dims[1]),
                                               static_cast<unsigned>(dims[2]));
    if(dims[2] <= 1) {
      T_ERROR("TIFF is not a volume; use "
              "`Load Dataset from Directory' instead!");
      TIFFClose(tif);
      return false;
    }
  }
  iHeaderSkip = 0;

  // read the number of bits per component from the tiff tag.
  {
    uint16_t bits_per_sample;
    TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bits_per_sample);
    iComponentSize = bits_per_sample;
    MESSAGE("%ld bits per component.", iComponentSize);
  }
  // likewise for the number of components / pixel.
  {
    uint16_t components;
    TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &components);
    iComponentCount = components;
    {
      std::ostringstream com;
      com << iComponentCount << " component";
      if(components > 1) { com << "s"; }
      com << ".";
      MESSAGE("%s", com.str().c_str());
    }
  }
  // Libtiff handles the endian issue for us.
  bConvertEndianess = false;

  // Data type/kind: signed or unsigned, floating point or not.
  {
    bSigned = false;
    bIsFloat = false;
    uint16_t sf;
    if(TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &sf) != 0) {
      bSigned = (sf == SAMPLEFORMAT_INT) || (sf == SAMPLEFORMAT_IEEEFP) ||
                (sf == SAMPLEFORMAT_COMPLEXINT);
      bIsFloat = (sf == SAMPLEFORMAT_IEEEFP);
    }
  }
  // Not sure if these are readable/stored in a TIFF.
  vVolumeAspect[0] = 1;
  vVolumeAspect[1] = 1;
  vVolumeAspect[2] = 1;

  strTitle = "TIFF Volume";
  eType = UVFTables::ES_UNDEFINED;

  // Create an intermediate file to hold the data.
  strIntermediateFile = strTempDir +
                        SysTools::GetFilename(strSourceFilename) + ".binary";
  LargeRAWFile binary(strIntermediateFile);
  binary.Create(iComponentSize/8 * iComponentCount * vVolumeSize.volume());
  if(!binary.IsOpen()) {
    T_ERROR("Could not create binary file %s", strIntermediateFile.c_str());

    TIFFClose(tif);
    return false;
  }
  bDeleteIntermediateFile = true;
  // Populate the intermediate file.  We'll do this slice-by-slice, which isn't
  // exactly kosher for this library -- a slice could technically be larger
  // than INCORESIZE.  But it won't be.
  unsigned slice_idx=0;
  do {
    MESSAGE("Reading %llux%llu TIFF slice %u of %llu",
            vVolumeSize[0], vVolumeSize[1], slice_idx++, vVolumeSize[2]-1);
    BYTE* slice = tv_read_slice(tif);
    if(slice) {
      // assuming 8-bit data here, which might not always be valid.
      binary.WriteRAW(static_cast<unsigned char*>(slice),
                      vVolumeSize[0]*vVolumeSize[1] *
                      sizeof(BYTE)*iComponentCount);
      _TIFFfree(slice);
    } else {
      binary.Close();
      binary.Delete();
      TIFFClose(tif);
      return false;
    }
  } while(TIFFReadDirectory(tif));
  binary.Close();

  TIFFClose(tif);
  return true;
#else
  T_ERROR("Tuvok was not built with IO support!");
  return false;
#endif
}

// unimplemented!
bool
TiffVolumeConverter::ConvertToNative(const std::string&,
                                     const std::string&,
                                     uint64_t, uint64_t,
                                     uint64_t, bool,
                                     bool,
                                     UINT64VECTOR3,
                                     FLOATVECTOR3,
                                     bool,
                                     bool)
{
  return false;
}

// Reads the dimensions of the TIFF volume.  X and Y come from the dimensions
// of the first image in the stack: we assume that this stays constant
// throughout the volume.  Z comes from the number of images in the stack.
static void
tv_dimensions(TIFF *tif, size_t dims[3])
{
#ifndef TUVOK_NO_IO
  uint32_t x,y;
  size_t z=0;

  TIFFSetDirectory(tif, 0);
  TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &x);
  // tiff calls the height "length" for some reason.
  TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &y);
  do {
    uint32_t tmpx, tmpy;
    TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &tmpx);
    TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &tmpy);
    if(tmpx != x) { WARNING("TIFF x dimension changes in stack!"); }
    if(tmpy != y) { WARNING("TIFF x dimension changes in stack!"); }
    ++z;
  } while(TIFFReadDirectory(tif));
  TIFFSetDirectory(tif, 0);

  dims[0] = x;
  dims[1] = y;
  dims[2] = z;
#endif
}

_malloc static BYTE*
tv_read_slice(TIFF *tif)
{
#ifdef TUVOK_NO_IO
  return NULL;
#else
  BYTE *slice;
  uint32_t width;
  uint32_t height;
  uint16_t bpp;
  uint16_t components;
  TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
  TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
  TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bpp);
  TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &components);

  if(bpp != 8) {
    T_ERROR("%hu-bit data is unsupported!", bpp);
    // Actually, this routine should handle it fine,
    // it's just that the caller and probably the rest
    // of Tuvok doesn't handle this well.
    return NULL;
  }

  const tsize_t slice_sz = width*height*(bpp/8)*components * sizeof(BYTE);
  slice = static_cast<BYTE*>(_TIFFmalloc(slice_sz));
  if(slice == NULL) {
    T_ERROR("TIFFmalloc failed.");
    return NULL;
  }

  const tstrip_t n_strips = TIFFNumberOfStrips(tif);
  {
    BYTE *data = slice;
    tdata_t buf = static_cast<tdata_t>(_TIFFmalloc(TIFFStripSize(tif)));
    // strips shouldn't be bigger than slices.
    assert(TIFFStripSize(tif) <= slice_sz);
    for(tstrip_t s=0; s < n_strips; ++s) {
      tsize_t n_bytes;
      n_bytes = TIFFReadEncodedStrip(tif, s, buf, static_cast<tsize_t>(-1));
      std::memcpy(data, buf, n_bytes);
      data += n_bytes;
    }
    _TIFFfree(buf);
  }

  return slice;
#endif
}
<commit_msg>replaced a another occurrence of the  BYTE data type with uint8_t<commit_after>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2008 Scientific Computing and Imaging Institute,
   University of Utah.

   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.
*/

/**
  \file    TiffVolumeConverter.h
  \author  Tom Fogal
           SCI Institute
           University of Utah
*/
#include <cstring>
#ifndef TUVOK_NO_IO
# include "3rdParty/tiff/tiffio.h"
#else
  struct TIFF;
#endif
#include "TiffVolumeConverter.h"
#include "../StdTuvokDefines.h"
#include "../Controller/Controller.h"
#include "../Basics/SysTools.h"

#ifdef __GNUC__
# define _malloc __attribute__((malloc))
#else
# define _malloc /* nothing */
#endif

static void tv_dimensions(TIFF *, size_t dims[3]);
_malloc static uint8_t* tv_read_slice(TIFF *);

TiffVolumeConverter::TiffVolumeConverter()
{
  m_vConverterDesc = "TIFF Volume (Image stack)";
#ifndef TUVOK_NO_IO
  m_vSupportedExt.push_back("OME.TIF");
  m_vSupportedExt.push_back("OME.TIFF");
  m_vSupportedExt.push_back("TIF");
  m_vSupportedExt.push_back("TIFF");
#endif
}

// converts a TiffVolume to a `raw' file.  We'll read through the TIFF
// slice-by-slice, copying each slice to the raw file.
bool
TiffVolumeConverter::ConvertToRAW(const std::string& strSourceFilename,
                                  const std::string& strTempDir,
                                  bool, uint64_t& iHeaderSkip,
                                  uint64_t& iComponentSize,
                                  uint64_t& iComponentCount,
                                  bool& bConvertEndianess, bool& bSigned,
                                  bool& bIsFloat, UINT64VECTOR3& vVolumeSize,
                                  FLOATVECTOR3& vVolumeAspect,
                                  std::string& strTitle,
                                  UVFTables::ElementSemanticTable& eType,
                                  std::string& strIntermediateFile,
                                  bool& bDeleteIntermediateFile)
{
#ifndef TUVOK_NO_IO
  MESSAGE("Attempting to convert TiffVolume: %s", strSourceFilename.c_str());

  TIFF *tif = TIFFOpen(strSourceFilename.c_str(), "r");
  if(tif == NULL) {
    T_ERROR("Could not open %s", strSourceFilename.c_str());
    return false;
  }

  // Get the dimensions of the volume.
  {
    size_t dims[3];
    tv_dimensions(tif, dims);
    vVolumeSize[0] = static_cast<uint64_t>(dims[0]);
    vVolumeSize[1] = static_cast<uint64_t>(dims[1]);
    vVolumeSize[2] = static_cast<uint64_t>(dims[2]);
    MESSAGE("TiffVolume dimensions: %ux%ux%u", static_cast<unsigned>(dims[0]),
                                               static_cast<unsigned>(dims[1]),
                                               static_cast<unsigned>(dims[2]));
    if(dims[2] <= 1) {
      T_ERROR("TIFF is not a volume; use "
              "`Load Dataset from Directory' instead!");
      TIFFClose(tif);
      return false;
    }
  }
  iHeaderSkip = 0;

  // read the number of bits per component from the tiff tag.
  {
    uint16_t bits_per_sample;
    TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bits_per_sample);
    iComponentSize = bits_per_sample;
    MESSAGE("%ld bits per component.", iComponentSize);
  }
  // likewise for the number of components / pixel.
  {
    uint16_t components;
    TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &components);
    iComponentCount = components;
    {
      std::ostringstream com;
      com << iComponentCount << " component";
      if(components > 1) { com << "s"; }
      com << ".";
      MESSAGE("%s", com.str().c_str());
    }
  }
  // Libtiff handles the endian issue for us.
  bConvertEndianess = false;

  // Data type/kind: signed or unsigned, floating point or not.
  {
    bSigned = false;
    bIsFloat = false;
    uint16_t sf;
    if(TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &sf) != 0) {
      bSigned = (sf == SAMPLEFORMAT_INT) || (sf == SAMPLEFORMAT_IEEEFP) ||
                (sf == SAMPLEFORMAT_COMPLEXINT);
      bIsFloat = (sf == SAMPLEFORMAT_IEEEFP);
    }
  }
  // Not sure if these are readable/stored in a TIFF.
  vVolumeAspect[0] = 1;
  vVolumeAspect[1] = 1;
  vVolumeAspect[2] = 1;

  strTitle = "TIFF Volume";
  eType = UVFTables::ES_UNDEFINED;

  // Create an intermediate file to hold the data.
  strIntermediateFile = strTempDir +
                        SysTools::GetFilename(strSourceFilename) + ".binary";
  LargeRAWFile binary(strIntermediateFile);
  binary.Create(iComponentSize/8 * iComponentCount * vVolumeSize.volume());
  if(!binary.IsOpen()) {
    T_ERROR("Could not create binary file %s", strIntermediateFile.c_str());

    TIFFClose(tif);
    return false;
  }
  bDeleteIntermediateFile = true;
  // Populate the intermediate file.  We'll do this slice-by-slice, which isn't
  // exactly kosher for this library -- a slice could technically be larger
  // than INCORESIZE.  But it won't be.
  unsigned slice_idx=0;
  do {
    MESSAGE("Reading %llux%llu TIFF slice %u of %llu",
            vVolumeSize[0], vVolumeSize[1], slice_idx++, vVolumeSize[2]-1);
    uint8_t* slice = tv_read_slice(tif);
    if(slice) {
      // assuming 8-bit data here, which might not always be valid.
      binary.WriteRAW(static_cast<unsigned char*>(slice),
                      vVolumeSize[0]*vVolumeSize[1] *
                      sizeof(uint8_t)*iComponentCount);
      _TIFFfree(slice);
    } else {
      binary.Close();
      binary.Delete();
      TIFFClose(tif);
      return false;
    }
  } while(TIFFReadDirectory(tif));
  binary.Close();

  TIFFClose(tif);
  return true;
#else
  T_ERROR("Tuvok was not built with IO support!");
  return false;
#endif
}

// unimplemented!
bool
TiffVolumeConverter::ConvertToNative(const std::string&,
                                     const std::string&,
                                     uint64_t, uint64_t,
                                     uint64_t, bool,
                                     bool,
                                     UINT64VECTOR3,
                                     FLOATVECTOR3,
                                     bool,
                                     bool)
{
  return false;
}

// Reads the dimensions of the TIFF volume.  X and Y come from the dimensions
// of the first image in the stack: we assume that this stays constant
// throughout the volume.  Z comes from the number of images in the stack.
static void
tv_dimensions(TIFF *tif, size_t dims[3])
{
#ifndef TUVOK_NO_IO
  uint32_t x,y;
  size_t z=0;

  TIFFSetDirectory(tif, 0);
  TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &x);
  // tiff calls the height "length" for some reason.
  TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &y);
  do {
    uint32_t tmpx, tmpy;
    TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &tmpx);
    TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &tmpy);
    if(tmpx != x) { WARNING("TIFF x dimension changes in stack!"); }
    if(tmpy != y) { WARNING("TIFF x dimension changes in stack!"); }
    ++z;
  } while(TIFFReadDirectory(tif));
  TIFFSetDirectory(tif, 0);

  dims[0] = x;
  dims[1] = y;
  dims[2] = z;
#endif
}

_malloc static uint8_t*
tv_read_slice(TIFF *tif)
{
#ifdef TUVOK_NO_IO
  return NULL;
#else
  uint8_t *slice;
  uint32_t width;
  uint32_t height;
  uint16_t bpp;
  uint16_t components;
  TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
  TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
  TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bpp);
  TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &components);

  if(bpp != 8) {
    T_ERROR("%hu-bit data is unsupported!", bpp);
    // Actually, this routine should handle it fine,
    // it's just that the caller and probably the rest
    // of Tuvok doesn't handle this well.
    return NULL;
  }

  const tsize_t slice_sz = width*height*(bpp/8)*components * sizeof(uint8_t);
  slice = static_cast<uint8_t*>(_TIFFmalloc(slice_sz));
  if(slice == NULL) {
    T_ERROR("TIFFmalloc failed.");
    return NULL;
  }

  const tstrip_t n_strips = TIFFNumberOfStrips(tif);
  {
    uint8_t *data = slice;
    tdata_t buf = static_cast<tdata_t>(_TIFFmalloc(TIFFStripSize(tif)));
    // strips shouldn't be bigger than slices.
    assert(TIFFStripSize(tif) <= slice_sz);
    for(tstrip_t s=0; s < n_strips; ++s) {
      tsize_t n_bytes;
      n_bytes = TIFFReadEncodedStrip(tif, s, buf, static_cast<tsize_t>(-1));
      std::memcpy(data, buf, n_bytes);
      data += n_bytes;
    }
    _TIFFfree(buf);
  }

  return slice;
#endif
}
<|endoftext|>


<commit_before>#include <Bull/Render/Shader/ShaderStageParameters.hpp>

namespace Bull
{
    ShaderStageParameters::ShaderStageParameters(ShaderStage::Type type)
    {
        setType(type);
    }

    ShaderStageParameters& ShaderStageParameters::setType(ShaderStage::Type type)
    {
        setParameter("type", type);

        return (*this);
    }

    ShaderStage::Type ShaderStageParameters::getType() const
    {
        unsigned int type = 0;

        getParameter("type", type);

        return static_cast<ShaderStage::Type>(type);
    }
}<commit_msg>[Render/ShaderStageParameter] Fix "type" value type<commit_after>#include <Bull/Render/Shader/ShaderStageParameters.hpp>

namespace Bull
{
    ShaderStageParameters::ShaderStageParameters(ShaderStage::Type type)
    {
        setType(type);
    }

    ShaderStageParameters& ShaderStageParameters::setType(ShaderStage::Type type)
    {
        setParameter("type", static_cast<unsigned int>(type));

        return (*this);
    }

    ShaderStage::Type ShaderStageParameters::getType() const
    {
        unsigned int type = 0;

        getParameter("type", type);

        return static_cast<ShaderStage::Type>(type);
    }
}<|endoftext|>


<commit_before>#include <bits/stdc++.h>
#define dbug(x) cout << '>' << #x << ':' << x << endl
#define pline    cout << "_________________________" << endl
#define mem(x, v) memset(x, v, sizeof(x))

#define eef else if
#define inpi inputt[i]
#define sf scanf
#define pf printf
#define i64 long long
#define ui64 unsigned long long

#define pcount(num)  __builtin_popcount(num)
#define all(x) x.begin(), x.end()
#define lla(x) x.rbegin(), x.rend()
#define SORT(c) sort(all(c))
#define ssort(v) stable_sort(v.begin(), v.end())
#define	sz(v) (int)(v).size()
#define _lst(X) (X)[sz((X))-1]

#define IT iterator
#define READ(f) freopen(f, "r", stdin)
#define WRITE(f) freopen(f, "w", stdout)
#define pb push_back
#define ppb pop_back
#define mp make_pair
#define fi first
#define se second
#define Contains(X,item) ((X).find(item) != (X).end())
#define CTN(T, x) (T.find(x) != T.end())
#define pb(...)      push_back(__VA_ARGS__)
#define eb(...)      emplace_back(__VA_ARGS__)
#define mp(x, y)     make_pair((x), (y))

#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
#define maximum(v)  *max_element(all(v)
#define minimum(v)  *min_element(all(v))
#define Reverse(x)  reverse(x.begin(),x.end())

#define ff(i,s,e) for(int i=(s);i<(int)(e);i++)
#define loop(i,s,e) for(__typeof(s) i=(s);i<=(e);i++)
#define pool(i,e,s) for(__typeof(e) i=(e);i>=(s);i--)

#define FORIT(i, m) for (__typeof((m).begin()) i=(m).begin(); i!=(m).end(); ++i)
#define foreach(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)

#define siter(n,T1)  for(set<T1>::iterator it=n.begin();it!=n.end();it++)
#define miter(n,T1,T2)  for(map<T1,T2>::iterator it=n.begin();it!=n.end();it++)
#define meter(n,T1,T2)  for(map<T1,T2>::iterator it=n.end();it!=n.begin();it--)

#define ps(x) cout<<"Case "<<++x<<": "
#define pcs(x) pf("Case %d: ", ++x)
#define newl '\n'
#define Newl "\n"
#define nl puts ("")
#define sqr(a) ((a)*(a))

#define PI 3.141592653589793
#define pi (2.0*acos(0.0))
#define pai acos(-1.0)
#define numdigit(x,y) (((int)(log10((x))/log10((y))))+1)

#define inf (1<<29)
#define MOD 1e9+7

#define eps 1e-9
#define INT(c)  ((int)((c) - '0'))
#define IOS ios_base::sync_with_stdio(0)

using namespace std;

int main(){
	//IOS;
	//READ("A.txt");
	float hours, minutes, newMinute, result1, result2;

	while ( scanf( "%f:%f", &hours,&minutes )==2 )
	{
		if((hours==0)&&(minutes==0))
            break;

		newMinute = (minutes / 5);
		result1 = ((((newMinute + 12) - hours) * 30) - ( minutes / 2 ));
		result2 = ((( hours - newMinute ) * 30) + ( minutes / 2 ));
		if (result2 < 0)
        {result2 = result2*(-1);
        }
        if (result1 >360)
        {
            result1 = 360 - result1;
        }

	if ( result1 > result2 )
	{
		printf("%.3f\n", result2);
	}

	else
	printf("%.3f\n", result1);

	}

	return 0;
}
<commit_msg>Delete 579-Clock-hands.cpp<commit_after><|endoftext|>


<commit_before>#include "Solver/LazyConstraintCallback.hpp"

#include <ilcplex/ilocplexi.h>

#include "Math.hpp"
#include "Solver.hpp"

using namespace std;

namespace xHeinz {
namespace solver {

 LazyConstraintCallback::LazyConstraintCallback( IloEnv env
                                               , Config const & conf
                                               , ExtChainGraph const & gs
                                               )
   : IloCplex::LazyConstraintCallbackI{ env }
   , Callback{ conf, gs } {
 }

 LazyConstraintCallback::LazyConstraintCallback( LazyConstraintCallback const & other )
   : IloCplex::LazyConstraintCallbackI{ other }
   , Callback{ other } {
 }

 IloCplex::CallbackI * LazyConstraintCallback::duplicateCallback() const {
   return new (getEnv()) LazyConstraintCallback( *this );
 }

 void LazyConstraintCallback::main() {
   assert( graphs.numGraphs() == 2 );
   for ( int i = 0, e = graphs.numGraphs(); i != e; ++i ) {
     processGraph( i );
   }
 }

 void LazyConstraintCallback::processGraph( int index ) {
   Graph const          & graph         = graphs.graph( index );
   GraphVariables const & vars          = graphs.variables( index );

   IloNumArray x_values{ getEnv(), vars.xVars.getSize() };
   getValues( x_values, vars.xVars );

   IloNumArray y_values{ getEnv(), vars.yVars.getSize() };
   getValues( y_values, vars.yVars );

   //printNonZeroX( x_values, index );
   //printNonZeroY( y_values, index );

   int nCuts = 0;
   NodeSetVector nonZeroNodesComponents;
   constructNonZeroComponents( graph, vars, x_values, nonZeroNodesComponents );

   if ( nonZeroNodesComponents.size() > 1 ) {
     Graph::Node root = determineRoot( graph, vars, y_values );
     separateConnectedComponents( graph
                                , vars
                                , root
                                , nonZeroNodesComponents
                                , nCuts
                                );
   }

   x_values.end();
   y_values.end();

   //clog << "Generated " << nCuts << " cuts" << endl;
 }

 void LazyConstraintCallback::separateConnectedComponents( Graph          const & g
                                                         , GraphVariables const & vars
                                                         , Graph::Node    const & root
                                                         , NodeSetVector  const & nonZeroNodesComponents
                                                         , int                  & nCuts
                                                         ) {
   IloExpr rhs( getEnv() );

   for ( const NodeSet& S : nonZeroNodesComponents ) {
     // only consider the non-zero components that don't contain the root
     if ( S.find( root ) == S.end() )
     {
       // determine dS
       NodeSet dS;
       for ( Graph::Node i : S ) {
         for ( Graph::Edge e : g.incEdges( i ) ) {
           Graph::Node j = g.oppositeNode( i, e );
           if ( S.find( j ) == S.end() )
           {
             dS.insert( j );
           }
         }
       }

       constructRHS( vars, dS, S, rhs );
       for ( Graph::Node i : S ) {
         assert( isValid( g, i, dS, S ) );
         add( vars.xVars[vars.nodeToIndex[i]] <= rhs, IloCplex::UseCutPurge ).end();
         ++nCuts;
       }
     }
   }

   rhs.end();
 }

 Graph::Node LazyConstraintCallback::determineRoot( Graph          const & g
                                                  , GraphVariables const & vars
                                                  , IloNumArray    const & y_values
                                                  ) const {
#if defined( DEBUG )
   Graph::Node root;
   int numRoots = 0;
   for ( Graph::Node const & n : g.nodes() ) {
     int nodeIndex = vars.nodeToIndex[n];
     if ( intIsNonZero( y_values[nodeIndex] ) ) {
       root = n;
       cerr << "Lazy DEBUG Label, root: " << g.label( n )
            << "   y value: " << y_values[nodeIndex]
            << (numRoots > 0 ? "  *" : "") << std::endl;
       ++numRoots;
     }
   }
   // do not use assert, since NDEBUG might be defined independantly from NDEBUG (used in assert)
   if ( numRoots != 1 ) {
     cerr << "More than one root detected in LazyConstraintCallback::determineRoot"
          << endl;
     std::abort();
   }
   return root;
#else
   auto it = find_if( g.nodes()
                    , [&]( Graph::Node const & n ) {
                        int nodeIndex = vars.nodeToIndex[n];
                        return intIsNonZero( y_values[nodeIndex] );
                      }
                    );
   assert( it != g.nodes().end() );
   return *it;
#endif
 }

} // namespace solver
} // namespace xHeinz

/* vim: set ts=8 sw=2 sts=2 et : */
<commit_msg>Correction of a rare heisenbug (thanks CPlex)<commit_after>#include "Solver/LazyConstraintCallback.hpp"

#include <ilcplex/ilocplexi.h>

#include "Math.hpp"
#include "Solver.hpp"

using namespace std;

namespace xHeinz {
namespace solver {

 LazyConstraintCallback::LazyConstraintCallback( IloEnv env
                                               , Config const & conf
                                               , ExtChainGraph const & gs
                                               )
   : IloCplex::LazyConstraintCallbackI{ env }
   , Callback{ conf, gs } {
 }

 LazyConstraintCallback::LazyConstraintCallback( LazyConstraintCallback const & other )
   : IloCplex::LazyConstraintCallbackI{ other }
   , Callback{ other } {
 }

 IloCplex::CallbackI * LazyConstraintCallback::duplicateCallback() const {
   return new (getEnv()) LazyConstraintCallback( *this );
 }

 void LazyConstraintCallback::main() {
   assert( graphs.numGraphs() == 2 );
   for ( int i = 0, e = graphs.numGraphs(); i != e; ++i ) {
     processGraph( i );
   }
 }

 void LazyConstraintCallback::processGraph( int index ) {
   Graph const          & graph         = graphs.graph( index );
   GraphVariables const & vars          = graphs.variables( index );

   IloNumArray x_values{ getEnv(), vars.xVars.getSize() };
   getValues( x_values, vars.xVars );

   IloNumArray y_values{ getEnv(), vars.yVars.getSize() };
   getValues( y_values, vars.yVars );

   //printNonZeroX( x_values, index );
   //printNonZeroY( y_values, index );

   int nCuts = 0;
   NodeSetVector nonZeroNodesComponents;
   constructNonZeroComponents( graph, vars, x_values, nonZeroNodesComponents );

   if ( nonZeroNodesComponents.size() > 1 ) {
     Graph::Node root = determineRoot( graph, vars, y_values );
     separateConnectedComponents( graph
                                , vars
                                , root
                                , nonZeroNodesComponents
                                , nCuts
                                );
   }

   x_values.end();
   y_values.end();

   //clog << "Generated " << nCuts << " cuts" << endl;
 }

 void LazyConstraintCallback::separateConnectedComponents( Graph          const & g
                                                         , GraphVariables const & vars
                                                         , Graph::Node    const & root
                                                         , NodeSetVector  const & nonZeroNodesComponents
                                                         , int                  & nCuts
                                                         ) {
   IloExpr rhs( getEnv() );

   for ( const NodeSet& S : nonZeroNodesComponents ) {
     // only consider the non-zero components that don't contain the root
     auto it = S.find( root );
     if ( it == S.end() || it->componentIndex() != root.componentIndex() ) {
       // determine dS
       NodeSet dS;
       for ( Graph::Node i : S ) {
         for ( Graph::Edge e : g.incEdges( i ) ) {
           Graph::Node j = g.oppositeNode( i, e );
           if ( S.find( j ) == S.end() )
           {
             dS.insert( j );
           }
         }
       }

       constructRHS( vars, dS, S, rhs );
       for ( Graph::Node i : S ) {
         assert( isValid( g, i, dS, S ) );
         add( vars.xVars[vars.nodeToIndex[i]] <= rhs, IloCplex::UseCutPurge ).end();
         ++nCuts;
       }
     }
   }

   rhs.end();
 }

 Graph::Node LazyConstraintCallback::determineRoot( Graph          const & g
                                                  , GraphVariables const & vars
                                                  , IloNumArray    const & y_values
                                                  ) const {
#if defined( DEBUG )
   Graph::Node root;
   int numRoots = 0;
   for ( Graph::Node const & n : g.nodes() ) {
     int nodeIndex = vars.nodeToIndex[n];
     if ( intIsNonZero( y_values[nodeIndex] ) ) {
       root = n;
       cerr << "Lazy DEBUG Label, root: " << g.label( n )
            << "   y value: " << y_values[nodeIndex]
            << (numRoots > 0 ? "  *" : "") << std::endl;
       ++numRoots;
     }
   }
   // do not use assert, since NDEBUG might be defined independantly from NDEBUG (used in assert)
   if ( numRoots != 1 ) {
     cerr << "More than one root detected in LazyConstraintCallback::determineRoot"
          << endl;
     std::abort();
   }
   return root;
#else
   auto it = find_if( g.nodes()
                    , [&]( Graph::Node const & n ) {
                        int nodeIndex = vars.nodeToIndex[n];
                        return intIsNonZero( y_values[nodeIndex] );
                      }
                    );
   assert( it != g.nodes().end() );
   return *it;
#endif
 }

} // namespace solver
} // namespace xHeinz

/* vim: set ts=8 sw=2 sts=2 et : */
<|endoftext|>


<commit_before>// StubExecutable.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "StubExecutable.h"

#include "semver200.h"

using namespace std;

wchar_t* FindRootAppDir()
{
	wchar_t* ourDirectory = new wchar_t[MAX_PATH];

	GetModuleFileName(GetModuleHandle(NULL), ourDirectory, MAX_PATH);
	wchar_t* lastSlash = wcsrchr(ourDirectory, L'\\');
	if (!lastSlash) {
		delete[] ourDirectory;
		return NULL;
	}

	// Null-terminate the string at the slash so now it's a directory
	*lastSlash = 0x0;
	return ourDirectory;
}

wchar_t* FindOwnExecutableName()
{
	wchar_t* ourDirectory = new wchar_t[MAX_PATH];

	GetModuleFileName(GetModuleHandle(NULL), ourDirectory, MAX_PATH);
	wchar_t* lastSlash = wcsrchr(ourDirectory, L'\\');
	if (!lastSlash) {
		delete[] ourDirectory;
		return NULL;
	}

	wchar_t* ret = _wcsdup(lastSlash + 1);
	delete[] ourDirectory;
	return ret;
}

std::wstring FindLatestAppDir()
{
	std::wstring ourDir;
	ourDir.assign(FindRootAppDir());

	ourDir += L"\\app-*";

	WIN32_FIND_DATA fileInfo = { 0 };
	HANDLE hFile = FindFirstFile(ourDir.c_str(), &fileInfo);
	if (hFile == INVALID_HANDLE_VALUE) {
		return NULL;
	}

	version::Semver200_version acc("0.0.0");
	std::wstring acc_s;

	do {
		std::wstring appVer = fileInfo.cFileName;
		appVer = appVer.substr(4);   // Skip 'app-'
		if (!(fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
			continue;
		}

		std::string s(appVer.begin(), appVer.end());

		version::Semver200_version thisVer(s);

		if (thisVer > acc) {
			acc = thisVer;
			acc_s = appVer;
		}
	} while (FindNextFile(hFile, &fileInfo));

	if (acc == version::Semver200_version("0.0.0")) {
		return NULL;
	}

	ourDir.assign(FindRootAppDir());
	std::wstringstream ret;
	ret << ourDir << L"\\app-" << acc_s;

	FindClose(hFile);
	return ret.str();
}

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
	std::wstring appName;
	appName.assign(FindOwnExecutableName());

	std::wstring fullPath = FindLatestAppDir();
	fullPath += L"\\" + appName;

	STARTUPINFO si = { 0 };
	PROCESS_INFORMATION pi = { 0 };

	si.cb = sizeof(si);
	si.dwFlags = STARTF_USESHOWWINDOW;
	si.wShowWindow = nCmdShow;

	if (!CreateProcess(fullPath.c_str(), lpCmdLine, NULL, NULL, true, 0, NULL, NULL, &si, &pi)) {
		return -1;
	}

	AllowSetForegroundWindow(pi.dwProcessId);
	WaitForSingleObject(pi.hProcess, INFINITE);

	DWORD dwExit = 0;
	GetExitCodeProcess(pi.hProcess, &dwExit);
	return dwExit;
}
<commit_msg>Don't hang around for the entire process lifetime, just leave once the app starts<commit_after>// StubExecutable.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "StubExecutable.h"

#include "semver200.h"

using namespace std;

wchar_t* FindRootAppDir()
{
	wchar_t* ourDirectory = new wchar_t[MAX_PATH];

	GetModuleFileName(GetModuleHandle(NULL), ourDirectory, MAX_PATH);
	wchar_t* lastSlash = wcsrchr(ourDirectory, L'\\');
	if (!lastSlash) {
		delete[] ourDirectory;
		return NULL;
	}

	// Null-terminate the string at the slash so now it's a directory
	*lastSlash = 0x0;
	return ourDirectory;
}

wchar_t* FindOwnExecutableName()
{
	wchar_t* ourDirectory = new wchar_t[MAX_PATH];

	GetModuleFileName(GetModuleHandle(NULL), ourDirectory, MAX_PATH);
	wchar_t* lastSlash = wcsrchr(ourDirectory, L'\\');
	if (!lastSlash) {
		delete[] ourDirectory;
		return NULL;
	}

	wchar_t* ret = _wcsdup(lastSlash + 1);
	delete[] ourDirectory;
	return ret;
}

std::wstring FindLatestAppDir()
{
	std::wstring ourDir;
	ourDir.assign(FindRootAppDir());

	ourDir += L"\\app-*";

	WIN32_FIND_DATA fileInfo = { 0 };
	HANDLE hFile = FindFirstFile(ourDir.c_str(), &fileInfo);
	if (hFile == INVALID_HANDLE_VALUE) {
		return NULL;
	}

	version::Semver200_version acc("0.0.0");
	std::wstring acc_s;

	do {
		std::wstring appVer = fileInfo.cFileName;
		appVer = appVer.substr(4);   // Skip 'app-'
		if (!(fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
			continue;
		}

		std::string s(appVer.begin(), appVer.end());

		version::Semver200_version thisVer(s);

		if (thisVer > acc) {
			acc = thisVer;
			acc_s = appVer;
		}
	} while (FindNextFile(hFile, &fileInfo));

	if (acc == version::Semver200_version("0.0.0")) {
		return NULL;
	}

	ourDir.assign(FindRootAppDir());
	std::wstringstream ret;
	ret << ourDir << L"\\app-" << acc_s;

	FindClose(hFile);
	return ret.str();
}

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
	std::wstring appName;
	appName.assign(FindOwnExecutableName());

	std::wstring fullPath = FindLatestAppDir();
	fullPath += L"\\" + appName;

	STARTUPINFO si = { 0 };
	PROCESS_INFORMATION pi = { 0 };

	si.cb = sizeof(si);
	si.dwFlags = STARTF_USESHOWWINDOW;
	si.wShowWindow = nCmdShow;

	if (!CreateProcess(fullPath.c_str(), lpCmdLine, NULL, NULL, true, 0, NULL, NULL, &si, &pi)) {
		return -1;
	}

	AllowSetForegroundWindow(pi.dwProcessId);
	WaitForInputIdle(pi.hProcess, 5 * 1000);
	return 0;
}
<|endoftext|>


<commit_before>/** Copyright (C) 2016 Ultimaker - Released under terms of the AGPLv3 License */
#include <cctype>
#include <fstream>
#include <stdio.h>
#include <sstream> // ostringstream
#include <regex> // regex parsing for temp flow graph
#include <string> // stod (string to double)
#include "../utils/logoutput.h"

#include "settings.h"
#include "SettingRegistry.h"

namespace cura
{
//c++11 no longer defines M_PI, so add our own constant.
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

std::string toString(EGCodeFlavor flavor)
{
    switch (flavor)
    {
        case EGCodeFlavor::BFB:
            return "BFB";
        case EGCodeFlavor::MACH3:
            return "Mach3";
        case EGCodeFlavor::MAKERBOT:
            return "Makerbot";
        case EGCodeFlavor::ULTIGCODE:
            return "UltiGCode";
        case EGCodeFlavor::REPRAP_VOLUMATRIC:
            return "RepRap(Volumetric)";
        case EGCodeFlavor::GRIFFIN:
            return "Griffin";
        case EGCodeFlavor::REPETIER:
            return "Repetier";
        case EGCodeFlavor::REPRAP:
        default:
            return "RepRap";
    }
}

SettingsBaseVirtual::SettingsBaseVirtual()
: parent(nullptr)
{
}

SettingsBaseVirtual::SettingsBaseVirtual(SettingsBaseVirtual* parent)
: parent(parent)
{
}

SettingsBase::SettingsBase()
: SettingsBaseVirtual(nullptr)
{
}

SettingsBase::SettingsBase(SettingsBaseVirtual* parent)
: SettingsBaseVirtual(parent)
{
}

SettingsMessenger::SettingsMessenger(SettingsBaseVirtual* parent)
: SettingsBaseVirtual(parent)
{
}

void SettingsBase::_setSetting(std::string key, std::string value)
{
    setting_values[key] = value;
}

void SettingsBase::setSetting(std::string key, std::string value)
{
    if (SettingRegistry::getInstance()->settingExists(key))
    {
        _setSetting(key, value);
    }
    else
    {
        cura::logWarning("Setting an unregistered setting %s to %s\n", key.c_str(), value.c_str());
        _setSetting(key, value); // Handy when programmers are in the process of introducing a new setting
    }
}

void SettingsBase::setSettingInheritBase(std::string key, const SettingsBaseVirtual& parent)
{
    setting_inherit_base.emplace(key, &parent);
}

std::string SettingsBase::getSettingString(std::string key) const
{
    if (setting_values.find(key) != setting_values.end())
    {
        return setting_values.at(key);
    }
    if (setting_inherit_base.find(key) != setting_inherit_base.end())
    {
        return setting_inherit_base.at(key)->getSettingString(key);
    }
    if (parent)
    {
        return parent->getSettingString(key);
    }

    const_cast<SettingsBase&>(*this).setting_values[key] = "";
    cura::logWarning("Unregistered setting %s\n", key.c_str());
    return "";
}

void SettingsMessenger::setSetting(std::string key, std::string value)
{
    parent->setSetting(key, value);
}

void SettingsMessenger::setSettingInheritBase(std::string key, const SettingsBaseVirtual& new_parent)
{
    parent->setSettingInheritBase(key, new_parent);
}

std::string SettingsMessenger::getSettingString(std::string key) const
{
    return parent->getSettingString(key);
}

int SettingsBaseVirtual::getSettingAsIndex(std::string key) const
{
    std::string value = getSettingString(key);
    return atoi(value.c_str());
}

int SettingsBaseVirtual::getSettingAsCount(std::string key) const
{
    std::string value = getSettingString(key);
    return atoi(value.c_str());
}

unsigned int SettingsBaseVirtual::getSettingAsLayerNumber(std::string key) const
{
    const unsigned int indicated_layer_number = stoul(getSettingString(key));
    if (indicated_layer_number < 1) //Input checking: Layer 0 is not allowed.
    {
        cura::logWarning("Invalid layer number %i for setting %s.", indicated_layer_number, key.c_str());
        return 0; //Assume layer 1.
    }
    return indicated_layer_number - 1; //Input starts counting at layer 1, but engine code starts counting at layer 0.
}

double SettingsBaseVirtual::getSettingInMillimeters(std::string key) const
{
    std::string value = getSettingString(key);
    return atof(value.c_str());
}

coord_t SettingsBaseVirtual::getSettingInMicrons(std::string key) const
{
    return getSettingInMillimeters(key) * 1000.0;
}

double SettingsBaseVirtual::getSettingInAngleDegrees(std::string key) const
{
    std::string value = getSettingString(key);
    return atof(value.c_str());
}

double SettingsBaseVirtual::getSettingInAngleRadians(std::string key) const
{
    std::string value = getSettingString(key);
    return atof(value.c_str()) / 180.0 * M_PI;
}

bool SettingsBaseVirtual::getSettingBoolean(std::string key) const
{
    std::string value = getSettingString(key);
    if (value == "on")
        return true;
    if (value == "yes")
        return true;
    if (value == "true" or value == "True") //Python uses "True"
        return true;
    int num = atoi(value.c_str());
    return num != 0;
}

double SettingsBaseVirtual::getSettingInDegreeCelsius(std::string key) const
{
    std::string value = getSettingString(key);
    return atof(value.c_str());
}

double SettingsBaseVirtual::getSettingInMillimetersPerSecond(std::string key) const
{
    std::string value = getSettingString(key);
    return std::max(0.0, atof(value.c_str()));
}

double SettingsBaseVirtual::getSettingInCubicMillimeters(std::string key) const
{
    std::string value = getSettingString(key);
    return std::max(0.0, atof(value.c_str()));
}

double SettingsBaseVirtual::getSettingInPercentage(std::string key) const
{
    std::string value = getSettingString(key);
    return std::max(0.0, atof(value.c_str()));
}

double SettingsBaseVirtual::getSettingAsRatio(std::string key) const
{
    std::string value = getSettingString(key);
    return atof(value.c_str()) / 100.0;
}

double SettingsBaseVirtual::getSettingInSeconds(std::string key) const
{
    std::string value = getSettingString(key);
    return std::max(0.0, atof(value.c_str()));
}

DraftShieldHeightLimitation SettingsBaseVirtual::getSettingAsDraftShieldHeightLimitation(const std::string key) const
{
    const std::string value = getSettingString(key);
    if (value == "full")
    {
        return DraftShieldHeightLimitation::FULL;
    }
    else if (value == "limited")
    {
        return DraftShieldHeightLimitation::LIMITED;
    }
    return DraftShieldHeightLimitation::FULL; //Default.
}

FlowTempGraph SettingsBaseVirtual::getSettingAsFlowTempGraph(std::string key) const
{
    FlowTempGraph ret;
    std::string value_string = getSettingString(key);
    if (value_string.empty())
    {
        return ret; //Empty at this point.
    }
    std::regex regex("(\\[([^,\\[]*),([^,\\]]*)\\])");
    // match with:
    // - the last opening bracket '['
    // - then a bunch of characters until the first comma
    // - a comma
    // - a bunch of cahracters until the first closing bracket ']'
    // matches with any substring which looks like "[  124.512 , 124.1 ]"

    // default constructor = end-of-sequence:
    std::regex_token_iterator<std::string::iterator> rend;

    int submatches[] = { 1, 2, 3 }; // match whole pair, first number and second number of a pair
    std::regex_token_iterator<std::string::iterator> match_iter(value_string.begin(), value_string.end(), regex, submatches);
    while (match_iter != rend)
    {
        match_iter++; // match the whole pair
        if (match_iter == rend)
        {
            break;
        }
        std::string first_substring = *match_iter++;
        std::string second_substring = *match_iter++;
        try
        {
            double first = std::stod(first_substring);
            double second = std::stod(second_substring);
            ret.data.emplace_back(first, second);
        }
        catch (const std::invalid_argument& e)
        {
            logError("Couldn't read 2D graph element [%s,%s] in setting '%s'. Ignored.\n", first_substring.c_str(), second_substring.c_str(), key.c_str());
        }
    }
    return ret;
}

FMatrix3x3 SettingsBaseVirtual::getSettingAsPointMatrix(std::string key) const
{
    FMatrix3x3 ret;

    std::string value_string = getSettingString(key);
    if (value_string.empty())
    {
        return ret; // standard matrix ([1,0,0],[0,1,0],[0,0,1])
    }

    std::string num("([^,\\] ]*)"); // match with anything but the next ',' ']' or space  and capture the match
    std::ostringstream row; // match with "[num,num,num]" and ignore whitespace
    row << "\\s*\\[\\s*" << num << "\\s*,\\s*" << num << "\\s*,\\s*" << num << "\\s*\\]\\s*";

    std::ostringstream matrix; // match with "[row,row,row]" and ignore whitespace
    matrix << "\\s*\\[" << row.str() << "\\s*,\\s*" << row.str() << "\\s*,\\s*" << row.str() << "\\]\\s*";

    std::regex point_matrix_regex(matrix.str());
    std::cmatch sub_matches;    // same as std::match_results<const char*> cm;
    std::regex_match(value_string.c_str(), sub_matches, point_matrix_regex);

    if (sub_matches.size() != 10) // one match for the whole string
    {
        logWarning("Mesh transformation matrix could not be parsed!\n\tFormat should be [[f,f,f],[f,f,f],[f,f,f]] allowing whitespace anywhere in between.\n\tWhile what was given was \"%s\".\n", value_string.c_str());
        return ret; // standard matrix ([1,0,0],[0,1,0],[0,0,1])
    }

    unsigned int sub_match_idx = 1; // skip the first because the first submatch is the whole string
    for (unsigned int x = 0; x < 3; x++)
    {
        for (unsigned int y = 0; y < 3; y++)
        {
            std::sub_match<const char*> sub_match = sub_matches[sub_match_idx];
            ret.m[y][x] = strtod(std::string(sub_match.str()).c_str(), nullptr);
            sub_match_idx++;
        }
    }

    return ret;
}

EGCodeFlavor SettingsBaseVirtual::getSettingAsGCodeFlavor(std::string key) const
{
    std::string value = getSettingString(key);
    if (value == "Griffin")
        return EGCodeFlavor::GRIFFIN;
    else if (value == "UltiGCode")
        return EGCodeFlavor::ULTIGCODE;
    else if (value == "Makerbot")
        return EGCodeFlavor::MAKERBOT;
    else if (value == "BFB")
        return EGCodeFlavor::BFB;
    else if (value == "MACH3")
        return EGCodeFlavor::MACH3;
    else if (value == "RepRap (Volumatric)")
        return EGCodeFlavor::REPRAP_VOLUMATRIC;
    else if (value == "Repetier")
        return EGCodeFlavor::REPETIER;
    return EGCodeFlavor::REPRAP;
}

EFillMethod SettingsBaseVirtual::getSettingAsFillMethod(std::string key) const
{
    std::string value = getSettingString(key);
    if (value == "lines")
        return EFillMethod::LINES;
    if (value == "grid")
        return EFillMethod::GRID;
    if (value == "cubic")
        return EFillMethod::CUBIC;
    if (value == "cubicsubdiv")
        return EFillMethod::CUBICSUBDIV;
    if (value == "tetrahedral")
        return EFillMethod::TETRAHEDRAL;
    if (value == "triangles")
        return EFillMethod::TRIANGLES;
    if (value == "concentric")
        return EFillMethod::CONCENTRIC;
    if (value == "concentric_3d")
        return EFillMethod::CONCENTRIC_3D;
    if (value == "zigzag")
        return EFillMethod::ZIG_ZAG;
    return EFillMethod::NONE;
}

EPlatformAdhesion SettingsBaseVirtual::getSettingAsPlatformAdhesion(std::string key) const
{
    std::string value = getSettingString(key);
    if (value == "brim")
        return EPlatformAdhesion::BRIM;
    if (value == "raft")
        return EPlatformAdhesion::RAFT;
    if (value == "none")
        return EPlatformAdhesion::NONE;
    return EPlatformAdhesion::SKIRT;
}

ESupportType SettingsBaseVirtual::getSettingAsSupportType(std::string key) const
{
    std::string value = getSettingString(key);
    if (value == "everywhere")
        return ESupportType::EVERYWHERE;
    if (value == "buildplate")
        return ESupportType::PLATFORM_ONLY;
    return ESupportType::NONE;
}

EZSeamType SettingsBaseVirtual::getSettingAsZSeamType(std::string key) const
{
    std::string value = getSettingString(key);
    if (value == "random")
        return EZSeamType::RANDOM;
    if (value == "shortest")
        return EZSeamType::SHORTEST;
    if (value == "back")
        return EZSeamType::BACK;
    return EZSeamType::SHORTEST;
}

ESurfaceMode SettingsBaseVirtual::getSettingAsSurfaceMode(std::string key) const
{
    std::string value = getSettingString(key);
    if (value == "normal")
        return ESurfaceMode::NORMAL;
    if (value == "surface")
        return ESurfaceMode::SURFACE;
    if (value == "both")
        return ESurfaceMode::BOTH;
    return ESurfaceMode::NORMAL;
}

FillPerimeterGapMode SettingsBaseVirtual::getSettingAsFillPerimeterGapMode(std::string key) const
{
    std::string value = getSettingString(key);
    if (value == "nowhere")
    {
        return FillPerimeterGapMode::NOWHERE;
    }
    if (value == "everywhere")
    {
        return FillPerimeterGapMode::EVERYWHERE;
    }
    return FillPerimeterGapMode::NOWHERE;
}

CombingMode SettingsBaseVirtual::getSettingAsCombingMode(std::string key)
{
    std::string value = getSettingString(key);
    if (value == "off")
    {
        return CombingMode::OFF;
    }
    if (value == "all")
    {
        return CombingMode::ALL;
    }
    if (value == "noskin")
    {
        return CombingMode::NO_SKIN;
    }
    return CombingMode::ALL;
}

SupportDistPriority SettingsBaseVirtual::getSettingAsSupportDistPriority(std::string key)
{
    std::string value = getSettingString(key);
    if (value == "xy_overrides_z")
    {
        return SupportDistPriority::XY_OVERRIDES_Z;
    }
    if (value == "z_overrides_xy")
    {
        return SupportDistPriority::Z_OVERRIDES_XY;
    }
    return SupportDistPriority::XY_OVERRIDES_Z;
}

}//namespace cura

<commit_msg>fix: error on unknown unset setting, rather than warn (CURA-3372)<commit_after>/** Copyright (C) 2016 Ultimaker - Released under terms of the AGPLv3 License */
#include <cctype>
#include <fstream>
#include <stdio.h>
#include <sstream> // ostringstream
#include <regex> // regex parsing for temp flow graph
#include <string> // stod (string to double)
#include "../utils/logoutput.h"

#include "settings.h"
#include "SettingRegistry.h"

namespace cura
{
//c++11 no longer defines M_PI, so add our own constant.
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

std::string toString(EGCodeFlavor flavor)
{
    switch (flavor)
    {
        case EGCodeFlavor::BFB:
            return "BFB";
        case EGCodeFlavor::MACH3:
            return "Mach3";
        case EGCodeFlavor::MAKERBOT:
            return "Makerbot";
        case EGCodeFlavor::ULTIGCODE:
            return "UltiGCode";
        case EGCodeFlavor::REPRAP_VOLUMATRIC:
            return "RepRap(Volumetric)";
        case EGCodeFlavor::GRIFFIN:
            return "Griffin";
        case EGCodeFlavor::REPETIER:
            return "Repetier";
        case EGCodeFlavor::REPRAP:
        default:
            return "RepRap";
    }
}

SettingsBaseVirtual::SettingsBaseVirtual()
: parent(nullptr)
{
}

SettingsBaseVirtual::SettingsBaseVirtual(SettingsBaseVirtual* parent)
: parent(parent)
{
}

SettingsBase::SettingsBase()
: SettingsBaseVirtual(nullptr)
{
}

SettingsBase::SettingsBase(SettingsBaseVirtual* parent)
: SettingsBaseVirtual(parent)
{
}

SettingsMessenger::SettingsMessenger(SettingsBaseVirtual* parent)
: SettingsBaseVirtual(parent)
{
}

void SettingsBase::_setSetting(std::string key, std::string value)
{
    setting_values[key] = value;
}

void SettingsBase::setSetting(std::string key, std::string value)
{
    if (SettingRegistry::getInstance()->settingExists(key))
    {
        _setSetting(key, value);
    }
    else
    {
        cura::logWarning("Setting an unregistered setting %s to %s\n", key.c_str(), value.c_str());
        _setSetting(key, value); // Handy when programmers are in the process of introducing a new setting
    }
}

void SettingsBase::setSettingInheritBase(std::string key, const SettingsBaseVirtual& parent)
{
    setting_inherit_base.emplace(key, &parent);
}

std::string SettingsBase::getSettingString(std::string key) const
{
    if (setting_values.find(key) != setting_values.end())
    {
        return setting_values.at(key);
    }
    if (setting_inherit_base.find(key) != setting_inherit_base.end())
    {
        return setting_inherit_base.at(key)->getSettingString(key);
    }
    if (parent)
    {
        return parent->getSettingString(key);
    }

    cura::logError("Trying to retrieve unregistered setting with no value given: '%s'\n", key.c_str());
    std::exit(-1);
    return "";
}

void SettingsMessenger::setSetting(std::string key, std::string value)
{
    parent->setSetting(key, value);
}

void SettingsMessenger::setSettingInheritBase(std::string key, const SettingsBaseVirtual& new_parent)
{
    parent->setSettingInheritBase(key, new_parent);
}

std::string SettingsMessenger::getSettingString(std::string key) const
{
    return parent->getSettingString(key);
}

int SettingsBaseVirtual::getSettingAsIndex(std::string key) const
{
    std::string value = getSettingString(key);
    return atoi(value.c_str());
}

int SettingsBaseVirtual::getSettingAsCount(std::string key) const
{
    std::string value = getSettingString(key);
    return atoi(value.c_str());
}

unsigned int SettingsBaseVirtual::getSettingAsLayerNumber(std::string key) const
{
    const unsigned int indicated_layer_number = stoul(getSettingString(key));
    if (indicated_layer_number < 1) //Input checking: Layer 0 is not allowed.
    {
        cura::logWarning("Invalid layer number %i for setting %s.", indicated_layer_number, key.c_str());
        return 0; //Assume layer 1.
    }
    return indicated_layer_number - 1; //Input starts counting at layer 1, but engine code starts counting at layer 0.
}

double SettingsBaseVirtual::getSettingInMillimeters(std::string key) const
{
    std::string value = getSettingString(key);
    return atof(value.c_str());
}

coord_t SettingsBaseVirtual::getSettingInMicrons(std::string key) const
{
    return getSettingInMillimeters(key) * 1000.0;
}

double SettingsBaseVirtual::getSettingInAngleDegrees(std::string key) const
{
    std::string value = getSettingString(key);
    return atof(value.c_str());
}

double SettingsBaseVirtual::getSettingInAngleRadians(std::string key) const
{
    std::string value = getSettingString(key);
    return atof(value.c_str()) / 180.0 * M_PI;
}

bool SettingsBaseVirtual::getSettingBoolean(std::string key) const
{
    std::string value = getSettingString(key);
    if (value == "on")
        return true;
    if (value == "yes")
        return true;
    if (value == "true" or value == "True") //Python uses "True"
        return true;
    int num = atoi(value.c_str());
    return num != 0;
}

double SettingsBaseVirtual::getSettingInDegreeCelsius(std::string key) const
{
    std::string value = getSettingString(key);
    return atof(value.c_str());
}

double SettingsBaseVirtual::getSettingInMillimetersPerSecond(std::string key) const
{
    std::string value = getSettingString(key);
    return std::max(0.0, atof(value.c_str()));
}

double SettingsBaseVirtual::getSettingInCubicMillimeters(std::string key) const
{
    std::string value = getSettingString(key);
    return std::max(0.0, atof(value.c_str()));
}

double SettingsBaseVirtual::getSettingInPercentage(std::string key) const
{
    std::string value = getSettingString(key);
    return std::max(0.0, atof(value.c_str()));
}

double SettingsBaseVirtual::getSettingAsRatio(std::string key) const
{
    std::string value = getSettingString(key);
    return atof(value.c_str()) / 100.0;
}

double SettingsBaseVirtual::getSettingInSeconds(std::string key) const
{
    std::string value = getSettingString(key);
    return std::max(0.0, atof(value.c_str()));
}

DraftShieldHeightLimitation SettingsBaseVirtual::getSettingAsDraftShieldHeightLimitation(const std::string key) const
{
    const std::string value = getSettingString(key);
    if (value == "full")
    {
        return DraftShieldHeightLimitation::FULL;
    }
    else if (value == "limited")
    {
        return DraftShieldHeightLimitation::LIMITED;
    }
    return DraftShieldHeightLimitation::FULL; //Default.
}

FlowTempGraph SettingsBaseVirtual::getSettingAsFlowTempGraph(std::string key) const
{
    FlowTempGraph ret;
    std::string value_string = getSettingString(key);
    if (value_string.empty())
    {
        return ret; //Empty at this point.
    }
    std::regex regex("(\\[([^,\\[]*),([^,\\]]*)\\])");
    // match with:
    // - the last opening bracket '['
    // - then a bunch of characters until the first comma
    // - a comma
    // - a bunch of cahracters until the first closing bracket ']'
    // matches with any substring which looks like "[  124.512 , 124.1 ]"

    // default constructor = end-of-sequence:
    std::regex_token_iterator<std::string::iterator> rend;

    int submatches[] = { 1, 2, 3 }; // match whole pair, first number and second number of a pair
    std::regex_token_iterator<std::string::iterator> match_iter(value_string.begin(), value_string.end(), regex, submatches);
    while (match_iter != rend)
    {
        match_iter++; // match the whole pair
        if (match_iter == rend)
        {
            break;
        }
        std::string first_substring = *match_iter++;
        std::string second_substring = *match_iter++;
        try
        {
            double first = std::stod(first_substring);
            double second = std::stod(second_substring);
            ret.data.emplace_back(first, second);
        }
        catch (const std::invalid_argument& e)
        {
            logError("Couldn't read 2D graph element [%s,%s] in setting '%s'. Ignored.\n", first_substring.c_str(), second_substring.c_str(), key.c_str());
        }
    }
    return ret;
}

FMatrix3x3 SettingsBaseVirtual::getSettingAsPointMatrix(std::string key) const
{
    FMatrix3x3 ret;

    std::string value_string = getSettingString(key);
    if (value_string.empty())
    {
        return ret; // standard matrix ([1,0,0],[0,1,0],[0,0,1])
    }

    std::string num("([^,\\] ]*)"); // match with anything but the next ',' ']' or space  and capture the match
    std::ostringstream row; // match with "[num,num,num]" and ignore whitespace
    row << "\\s*\\[\\s*" << num << "\\s*,\\s*" << num << "\\s*,\\s*" << num << "\\s*\\]\\s*";

    std::ostringstream matrix; // match with "[row,row,row]" and ignore whitespace
    matrix << "\\s*\\[" << row.str() << "\\s*,\\s*" << row.str() << "\\s*,\\s*" << row.str() << "\\]\\s*";

    std::regex point_matrix_regex(matrix.str());
    std::cmatch sub_matches;    // same as std::match_results<const char*> cm;
    std::regex_match(value_string.c_str(), sub_matches, point_matrix_regex);

    if (sub_matches.size() != 10) // one match for the whole string
    {
        logWarning("Mesh transformation matrix could not be parsed!\n\tFormat should be [[f,f,f],[f,f,f],[f,f,f]] allowing whitespace anywhere in between.\n\tWhile what was given was \"%s\".\n", value_string.c_str());
        return ret; // standard matrix ([1,0,0],[0,1,0],[0,0,1])
    }

    unsigned int sub_match_idx = 1; // skip the first because the first submatch is the whole string
    for (unsigned int x = 0; x < 3; x++)
    {
        for (unsigned int y = 0; y < 3; y++)
        {
            std::sub_match<const char*> sub_match = sub_matches[sub_match_idx];
            ret.m[y][x] = strtod(std::string(sub_match.str()).c_str(), nullptr);
            sub_match_idx++;
        }
    }

    return ret;
}

EGCodeFlavor SettingsBaseVirtual::getSettingAsGCodeFlavor(std::string key) const
{
    std::string value = getSettingString(key);
    if (value == "Griffin")
        return EGCodeFlavor::GRIFFIN;
    else if (value == "UltiGCode")
        return EGCodeFlavor::ULTIGCODE;
    else if (value == "Makerbot")
        return EGCodeFlavor::MAKERBOT;
    else if (value == "BFB")
        return EGCodeFlavor::BFB;
    else if (value == "MACH3")
        return EGCodeFlavor::MACH3;
    else if (value == "RepRap (Volumatric)")
        return EGCodeFlavor::REPRAP_VOLUMATRIC;
    else if (value == "Repetier")
        return EGCodeFlavor::REPETIER;
    return EGCodeFlavor::REPRAP;
}

EFillMethod SettingsBaseVirtual::getSettingAsFillMethod(std::string key) const
{
    std::string value = getSettingString(key);
    if (value == "lines")
        return EFillMethod::LINES;
    if (value == "grid")
        return EFillMethod::GRID;
    if (value == "cubic")
        return EFillMethod::CUBIC;
    if (value == "cubicsubdiv")
        return EFillMethod::CUBICSUBDIV;
    if (value == "tetrahedral")
        return EFillMethod::TETRAHEDRAL;
    if (value == "triangles")
        return EFillMethod::TRIANGLES;
    if (value == "concentric")
        return EFillMethod::CONCENTRIC;
    if (value == "concentric_3d")
        return EFillMethod::CONCENTRIC_3D;
    if (value == "zigzag")
        return EFillMethod::ZIG_ZAG;
    return EFillMethod::NONE;
}

EPlatformAdhesion SettingsBaseVirtual::getSettingAsPlatformAdhesion(std::string key) const
{
    std::string value = getSettingString(key);
    if (value == "brim")
        return EPlatformAdhesion::BRIM;
    if (value == "raft")
        return EPlatformAdhesion::RAFT;
    if (value == "none")
        return EPlatformAdhesion::NONE;
    return EPlatformAdhesion::SKIRT;
}

ESupportType SettingsBaseVirtual::getSettingAsSupportType(std::string key) const
{
    std::string value = getSettingString(key);
    if (value == "everywhere")
        return ESupportType::EVERYWHERE;
    if (value == "buildplate")
        return ESupportType::PLATFORM_ONLY;
    return ESupportType::NONE;
}

EZSeamType SettingsBaseVirtual::getSettingAsZSeamType(std::string key) const
{
    std::string value = getSettingString(key);
    if (value == "random")
        return EZSeamType::RANDOM;
    if (value == "shortest")
        return EZSeamType::SHORTEST;
    if (value == "back")
        return EZSeamType::BACK;
    return EZSeamType::SHORTEST;
}

ESurfaceMode SettingsBaseVirtual::getSettingAsSurfaceMode(std::string key) const
{
    std::string value = getSettingString(key);
    if (value == "normal")
        return ESurfaceMode::NORMAL;
    if (value == "surface")
        return ESurfaceMode::SURFACE;
    if (value == "both")
        return ESurfaceMode::BOTH;
    return ESurfaceMode::NORMAL;
}

FillPerimeterGapMode SettingsBaseVirtual::getSettingAsFillPerimeterGapMode(std::string key) const
{
    std::string value = getSettingString(key);
    if (value == "nowhere")
    {
        return FillPerimeterGapMode::NOWHERE;
    }
    if (value == "everywhere")
    {
        return FillPerimeterGapMode::EVERYWHERE;
    }
    return FillPerimeterGapMode::NOWHERE;
}

CombingMode SettingsBaseVirtual::getSettingAsCombingMode(std::string key)
{
    std::string value = getSettingString(key);
    if (value == "off")
    {
        return CombingMode::OFF;
    }
    if (value == "all")
    {
        return CombingMode::ALL;
    }
    if (value == "noskin")
    {
        return CombingMode::NO_SKIN;
    }
    return CombingMode::ALL;
}

SupportDistPriority SettingsBaseVirtual::getSettingAsSupportDistPriority(std::string key)
{
    std::string value = getSettingString(key);
    if (value == "xy_overrides_z")
    {
        return SupportDistPriority::XY_OVERRIDES_Z;
    }
    if (value == "z_overrides_xy")
    {
        return SupportDistPriority::Z_OVERRIDES_XY;
    }
    return SupportDistPriority::XY_OVERRIDES_Z;
}

}//namespace cura

<|endoftext|>


<commit_before>#pragma once

#include "file_monitor.hpp"
#include "spdlog_utility.hpp"
#include <fstream>
#include <list>

class log_monitor final {
public:
  log_monitor(const log_monitor&) = delete;

  log_monitor(void) {
    for (const auto& file_path : {
             "/var/log/karabiner/grabber_log.1.txt",
             "/var/log/karabiner/grabber_log.txt",
             "/var/log/karabiner/event_dispatcher_log.txt",
         }) {
      add_lines(file_path);
    }

    for (const auto& it : lines_) {
      std::cout << it.second << std::endl;
    }
  }

private:
  void add_lines(const std::string& file_path) {
    std::ifstream stream(file_path);
    std::string line;
    while (std::getline(stream, line)) {
      if (add_line(line)) {
        const size_t max_lines = 250;
        while (lines_.size() > max_lines) {
          lines_.pop_front();
        }
      }
    }
  }

  bool add_line(const std::string& line) {
    if (auto sort_key = spdlog_utility::get_sort_key(line)) {
      if (lines_.empty()) {
        lines_.push_back(std::make_pair(*sort_key, line));
        return true;
      }

      if (*sort_key < lines_.front().first) {
        // line is too old
        return false;
      }

      if (*sort_key > lines_.back().first) {
        lines_.push_back(std::make_pair(*sort_key, line));
        return true;
      }

      for (auto it = lines_.begin(); it != lines_.end(); ++it) {
        if (*sort_key < it->first) {
          lines_.insert(it, std::make_pair(*sort_key, line));
          return true;
        }
      }

      lines_.push_back(std::make_pair(*sort_key, line));
      return true;
    }

    return false;
  }

  std::list<std::pair<uint64_t, std::string>> lines_;
  std::unique_ptr<file_monitor> file_monitor_;
};
<commit_msg>remove debug output<commit_after>#pragma once

#include "file_monitor.hpp"
#include "spdlog_utility.hpp"
#include <fstream>
#include <list>

class log_monitor final {
public:
  log_monitor(const log_monitor&) = delete;

  log_monitor(void) {
    for (const auto& file_path : {
             "/var/log/karabiner/grabber_log.1.txt",
             "/var/log/karabiner/grabber_log.txt",
             "/var/log/karabiner/event_dispatcher_log.txt",
         }) {
      add_lines(file_path);
    }
  }

private:
  void add_lines(const std::string& file_path) {
    std::ifstream stream(file_path);
    std::string line;
    while (std::getline(stream, line)) {
      if (add_line(line)) {
        const size_t max_lines = 250;
        while (lines_.size() > max_lines) {
          lines_.pop_front();
        }
      }
    }
  }

  bool add_line(const std::string& line) {
    if (auto sort_key = spdlog_utility::get_sort_key(line)) {
      if (lines_.empty()) {
        lines_.push_back(std::make_pair(*sort_key, line));
        return true;
      }

      if (*sort_key < lines_.front().first) {
        // line is too old
        return false;
      }

      if (*sort_key > lines_.back().first) {
        lines_.push_back(std::make_pair(*sort_key, line));
        return true;
      }

      for (auto it = lines_.begin(); it != lines_.end(); ++it) {
        if (*sort_key < it->first) {
          lines_.insert(it, std::make_pair(*sort_key, line));
          return true;
        }
      }

      lines_.push_back(std::make_pair(*sort_key, line));
      return true;
    }

    return false;
  }

  std::list<std::pair<uint64_t, std::string>> lines_;
  std::unique_ptr<file_monitor> file_monitor_;
};
<|endoftext|>


<commit_before>/* vim: set ts=2 expandtab: */
/**
 *       @file  test.cpp
 *      @brief
 *
 *     @author  Josh King (jheretic), jking@chambana.net
 *
 *   @internal
 *      Created  11/17/2013 06:01:11 PM
 *     Compiler  gcc/g++
 * Organization  The Open Technology Institute
 *    Copyright  Copyright (c) 2013, Josh King
 *
 * This file is part of Commotion, Copyright (c) 2013, Josh King
 *
 * Commotion is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 *
 * Commotion 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Commotion.  If not, see <http://www.gnu.org/licenses/>.
 *
 * =====================================================================================
 */
extern "C" {
#include "../src/obj.h"
#include "../src/list.h"
#include "../src/tree.h"
}
#include "gtest/gtest.h"

class TreeTest : public ::testing::Test
{
  protected:
    co_obj_t *Tree16;
    co_obj_t *Tree32;
    void InsertObj();
    void DeleteObj();

    TreeTest()
    {
      Tree16 = co_tree16_create();
      Tree32 = co_tree32_create();
    }

    virtual void SetUp()
    {
    }

    ~TreeTest()
    {
      co_obj_free(Tree16);
      co_obj_free(Tree32);
    }
};

void TreeTest::InsertObj()
{
  co_obj_t *TestString1 = co_bin8_create("1TESTVALUE1", 11, 0);
  int ret = co_tree_insert(Tree16, "1TESTKEY1", 10, TestString1);
  ASSERT_EQ(1, ret);
  co_obj_t *ptr = co_tree_find(Tree16, "1TESTKEY1", 10);
  ASSERT_EQ(TestString1, ptr);
  co_obj_t *TestString2 = co_bin8_create("2TESTVALUE2", 12, 0);
  ret = co_tree_insert(Tree16, "2TESTKEY2", 10, TestString2);
  ASSERT_EQ(1, ret);
  ptr = co_tree_find(Tree16, "2TESTKEY2", 10);
  ASSERT_EQ(TestString2, ptr);
  ret = co_tree_insert(Tree32, "1TESTKEY1", 10, TestString1);
  ASSERT_EQ(1, ret);
  ptr = co_tree_find(Tree32, "1TESTKEY1", 10);
  ASSERT_EQ(TestString1, ptr);
  ret = co_tree_insert(Tree32, "2TESTKEY2", 10, TestString2);
  ASSERT_EQ(1, ret);
  ptr = co_tree_find(Tree32, "2TESTKEY2", 10);
  ASSERT_EQ(TestString2, ptr);
}

void TreeTest::DeleteObj()
{
  co_obj_t *TestString1 = co_bin8_create("1TESTVALUE1", 11, 0);
  int ret = co_tree_insert(Tree16, "1TESTKEY1", 9, TestString1);
  ASSERT_EQ(1, ret);
  co_obj_t *ptr = co_tree_delete(Tree16, "1TESTKEY1", 9);
  ASSERT_EQ(TestString1, ptr);
  co_obj_t *TestString2 = co_bin8_create("2TESTVALUE2", 11, 0);
  ret = co_tree_insert(Tree16, "2TESTKEY2", 9, TestString2);
  ASSERT_EQ(1, ret);
  ptr = co_tree_delete(Tree16, "2TESTKEY2", 9);
  ASSERT_EQ(TestString2, ptr);
}

TEST_F(TreeTest, TreeInsertTest)
{
  InsertObj();
}

TEST_F(TreeTest, TreeDeleteTest)
{
  DeleteObj();
}
<commit_msg>optimized test set up<commit_after>/* vim: set ts=2 expandtab: */
/**
 *       @file  test.cpp
 *      @brief
 *
 *     @author  Josh King (jheretic), jking@chambana.net
 *
 *   @internal
 *      Created  11/17/2013 06:01:11 PM
 *     Compiler  gcc/g++
 * Organization  The Open Technology Institute
 *    Copyright  Copyright (c) 2013, Josh King
 *
 * This file is part of Commotion, Copyright (c) 2013, Josh King
 *
 * Commotion is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 *
 * Commotion 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Commotion.  If not, see <http://www.gnu.org/licenses/>.
 *
 * =====================================================================================
 */
extern "C" {
#include "../src/obj.h"
#include "../src/list.h"
#include "../src/tree.h"
}
#include "gtest/gtest.h"

/*
 * NOTE: Inserting keys with different length values will be interpreted as different keys (eg insert("test", 5) and insert("test", 6) are not the same
 * and their values will be stored in different nodes in the tree
 *
 *
 */

class TreeTest : public ::testing::Test
{
  protected:
    co_obj_t *Tree16;
    co_obj_t *Tree32;
    void InsertObj();
    void DeleteObj();
    co_obj_t *TestString1;
    co_obj_t *TestString2;

    int ret;

    TreeTest()
    {
      Tree16 = co_tree16_create();
      Tree32 = co_tree32_create();

      TestString1 = co_str8_create("1TESTVALUE1", 11, 0);
      TestString2 = co_str8_create("2TESTVALUE2", 12, 0);

      int ret = NULL;

    }

    virtual void SetUp()
    {
    }

    ~TreeTest()
    {
      co_obj_free(Tree16);
      co_obj_free(Tree32);
    }
};

void TreeTest::InsertObj()
{
  ret = co_tree_insert(Tree16, "1TESTKEY1", 10, TestString1);
  ASSERT_EQ(1, ret);

  co_obj_t *ptr = co_tree_find(Tree16, "1TESTKEY1", 10);
  ASSERT_EQ(TestString1, ptr);

  ret = co_tree_insert(Tree16, "2TESTKEY2", 10, TestString2);
  ASSERT_EQ(1, ret);

  ptr = co_tree_find(Tree16, "2TESTKEY2", 10);
  ASSERT_EQ(TestString2, ptr);

  ret = co_tree_insert(Tree32, "1TESTKEY1", 10, TestString1);
  ASSERT_EQ(1, ret);

  ptr = co_tree_find(Tree32, "1TESTKEY1", 10);
  ASSERT_EQ(TestString1, ptr);

  ret = co_tree_insert(Tree32, "2TESTKEY2", 10, TestString2);
  ASSERT_EQ(1, ret);

  ptr = co_tree_find(Tree32, "2TESTKEY2", 10);
  ASSERT_EQ(TestString2, ptr);
}

void TreeTest::DeleteObj()
{

  ret = co_tree_insert(Tree16, "1TESTKEY1", 9, TestString1);
  ASSERT_EQ(1, ret);

  co_obj_t *ptr = co_tree_delete(Tree16, "1TESTKEY1", 9);
  ASSERT_EQ(TestString1, ptr);

  // co_obj_t *TestString2 = co_bin8_create("2TESTVALUE2", 11, 0);
  ret = co_tree_insert(Tree16, "2TESTKEY2", 9, TestString2);
  ASSERT_EQ(1, ret);

  ptr = co_tree_delete(Tree16, "2TESTKEY2", 9);
  ASSERT_EQ(TestString2, ptr);

  // repeat for Tree32

}

TEST_F(TreeTest, TreeInsertTest)
{
  InsertObj();
}

TEST_F(TreeTest, TreeDeleteTest)
{
  DeleteObj();
}
<|endoftext|>