<commit_before>// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++0x -fms-extensions %s

#define P(e) static_assert(noexcept(e), "expected nothrow")
#define N(e) static_assert(!noexcept(e), "expected throw")
#define B(b, e) static_assert(b == noexcept(e), "expectation failed")

void simple() {
  P(0);
  P(0 + 0);
  int i;
  P(i);
  P(sizeof(0));
  P(static_cast<int>(0));
  N(throw 0);
  N((throw 0, 0));
}

void nospec();
void allspec() throw(...);
void intspec() throw(int);
void emptyspec() throw();
void nothrowattr() __attribute__((nothrow));

void call() {
  N(nospec());
  N(allspec());
  N(intspec());
  P(emptyspec());
  P(nothrowattr());
}

void (*pnospec)();
void (*pallspec)() throw(...);
void (*pintspec)() throw(int);
void (*pemptyspec)() throw();

void callptr() {
  N(pnospec());
  N((*pnospec)());
  N(pallspec());
  N((*pallspec)());
  N(pintspec());
  N((*pintspec)());
  P(pemptyspec());
  P((*pemptyspec)());
}

struct S1 {
  void nospec();
  void allspec() throw(...);
  void intspec() throw(int);
  void emptyspec() throw();
};

void callmem() {
  S1 s;
  N(s.nospec());
  N(s.allspec());
  N(s.intspec());
  P(s.emptyspec());
}

void (S1::*mpnospec)();
void (S1::*mpallspec)() throw(...);
void (S1::*mpintspec)() throw(int);
void (S1::*mpemptyspec)() throw();

void callmemptr() {
  S1 s;
  N((s.*mpnospec)());
  N((s.*mpallspec)());
  N((s.*mpintspec)());
  P((s.*mpemptyspec)());
}

struct S2 {
  S2();
  S2(int, int) throw();
  void operator +();
  void operator -() throw();
  void operator +(int);
  void operator -(int) throw();
  operator int();
  operator float() throw();
};

void *operator new(__typeof__(sizeof(int)) sz, int) throw();

struct Bad1 {
  ~Bad1() throw(int);
};
struct Bad2 {
  void operator delete(void*) throw(int);
};

void implicits() {
  N(new int);
  P(new (0) int);
  P(delete (int*)0);
  N(delete (Bad1*)0);
  N(delete (Bad2*)0);
  N(S2());
  P(S2(0, 0));
  S2 s;
  N(+s);
  P(-s);
  N(s + 0);
  P(s - 0);
  N(static_cast<int>(s));
  P(static_cast<float>(s));
  N(Bad1());
}

struct V {
  virtual ~V() throw();
};
struct D : V {};

void dyncast() {
  V *pv = 0;
  D *pd = 0;
  P(dynamic_cast<V&>(*pd));
  P(dynamic_cast<V*>(pd));
  N(dynamic_cast<D&>(*pv));
  P(dynamic_cast<D*>(pv));
}

namespace std {
  struct type_info {};
}

void idtype() {
  P(typeid(V));
  P(typeid((V*)0));
  P(typeid(*(S1*)0));
  N(typeid(*(V*)0));
}

void uneval() {
  P(sizeof(typeid(*(V*)0)));
  P(typeid(typeid(*(V*)0)));
}

struct G1 {};
struct G2 { int i; };
struct G3 { S2 s; };

void gencon() {
  P(G1());
  P(G2());
  N(G3());
}

template <typename T, bool b>
void late() {
  B(b, typeid(*(T*)0));
  B(b, T(1));
  B(b, static_cast<T>(S2(0, 0)));
  B(b, S1() + T());
}
struct S3 {
  virtual ~S3() throw();
  S3() throw();
  explicit S3(int);
  S3(const S2&);
};
void operator +(const S1&, float) throw();
void operator +(const S1&, const S3&);
void tlate() {
  late<float, true>();
  late<S3, false>();
}
<commit_msg>Extend the noexcept expression test to test noexcept specification functions.<commit_after>// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++0x -fms-extensions %s

#define P(e) static_assert(noexcept(e), "expected nothrow")
#define N(e) static_assert(!noexcept(e), "expected throw")
#define B(b, e) static_assert(b == noexcept(e), "expectation failed")

void simple() {
  P(0);
  P(0 + 0);
  int i;
  P(i);
  P(sizeof(0));
  P(static_cast<int>(0));
  N(throw 0);
  N((throw 0, 0));
}

void nospec();
void allspec() throw(...);
void intspec() throw(int);
void emptyspec() throw();
void nothrowattr() __attribute__((nothrow));
void noexcept_true() noexcept;
void noexcept_false() noexcept(false);

void call() {
  N(nospec());
  N(allspec());
  N(intspec());
  P(emptyspec());
  P(nothrowattr());
  P(noexcept_true());
  N(noexcept_false());
}

void (*pnospec)();
void (*pallspec)() throw(...);
void (*pintspec)() throw(int);
void (*pemptyspec)() throw();

void callptr() {
  N(pnospec());
  N((*pnospec)());
  N(pallspec());
  N((*pallspec)());
  N(pintspec());
  N((*pintspec)());
  P(pemptyspec());
  P((*pemptyspec)());
}

struct S1 {
  void nospec();
  void allspec() throw(...);
  void intspec() throw(int);
  void emptyspec() throw();
};

void callmem() {
  S1 s;
  N(s.nospec());
  N(s.allspec());
  N(s.intspec());
  P(s.emptyspec());
}

void (S1::*mpnospec)();
void (S1::*mpallspec)() throw(...);
void (S1::*mpintspec)() throw(int);
void (S1::*mpemptyspec)() throw();

void callmemptr() {
  S1 s;
  N((s.*mpnospec)());
  N((s.*mpallspec)());
  N((s.*mpintspec)());
  P((s.*mpemptyspec)());
}

struct S2 {
  S2();
  S2(int, int) throw();
  void operator +();
  void operator -() throw();
  void operator +(int);
  void operator -(int) throw();
  operator int();
  operator float() throw();
};

void *operator new(__typeof__(sizeof(int)) sz, int) throw();

struct Bad1 {
  ~Bad1() throw(int);
};
struct Bad2 {
  void operator delete(void*) throw(int);
};

void implicits() {
  N(new int);
  P(new (0) int);
  P(delete (int*)0);
  N(delete (Bad1*)0);
  N(delete (Bad2*)0);
  N(S2());
  P(S2(0, 0));
  S2 s;
  N(+s);
  P(-s);
  N(s + 0);
  P(s - 0);
  N(static_cast<int>(s));
  P(static_cast<float>(s));
  N(Bad1());
}

struct V {
  virtual ~V() throw();
};
struct D : V {};

void dyncast() {
  V *pv = 0;
  D *pd = 0;
  P(dynamic_cast<V&>(*pd));
  P(dynamic_cast<V*>(pd));
  N(dynamic_cast<D&>(*pv));
  P(dynamic_cast<D*>(pv));
}

namespace std {
  struct type_info {};
}

void idtype() {
  P(typeid(V));
  P(typeid((V*)0));
  P(typeid(*(S1*)0));
  N(typeid(*(V*)0));
}

void uneval() {
  P(sizeof(typeid(*(V*)0)));
  P(typeid(typeid(*(V*)0)));
}

struct G1 {};
struct G2 { int i; };
struct G3 { S2 s; };

void gencon() {
  P(G1());
  P(G2());
  N(G3());
}

template <typename T, bool b>
void late() {
  B(b, typeid(*(T*)0));
  B(b, T(1));
  B(b, static_cast<T>(S2(0, 0)));
  B(b, S1() + T());
}
struct S3 {
  virtual ~S3() throw();
  S3() throw();
  explicit S3(int);
  S3(const S2&);
};
void operator +(const S1&, float) throw();
void operator +(const S1&, const S3&);
void tlate() {
  late<float, true>();
  late<S3, false>();
}
<|endoftext|>


<commit_before>/*
    Copyright (c) 2010 Tobias Koenig <tokoe@kde.org>

    This library is free software; you can redistribute it and/or modify it
    under the terms of the GNU Library General Public License as published by
    the Free Software Foundation; either version 2 of the License, or (at your
    option) any later version.

    This library 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 Library General Public
    License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
*/

#include "dbconfig.h"

#include "dbconfigmysql.h"
#include "dbconfigmysqlembedded.h"
#include "dbconfigpostgresql.h"
#include "dbconfigsqlite.h"

#include <akdebug.h>
#include <libs/xdgbasedirs_p.h>

using namespace Akonadi;

//TODO: make me Q_GLOBAL_STATIC
static DbConfig *s_DbConfigInstance = 0;

DbConfig::DbConfig()
{
  const QString serverConfigFile = XdgBaseDirs::akonadiServerConfigFile( XdgBaseDirs::ReadWrite );
  QSettings settings( serverConfigFile, QSettings::IniFormat );

  mSizeThreshold = 4096;
  const QVariant value = settings.value( QLatin1String( "General/SizeThreshold" ), mSizeThreshold );
  if ( value.canConvert<qint64>() )
    mSizeThreshold = value.value<qint64>();
  else
    mSizeThreshold = 0;

  if ( mSizeThreshold < 0 )
    mSizeThreshold = 0;

  mUseExternalPayloadFile = true;
  mUseExternalPayloadFile = settings.value( QLatin1String( "General/ExternalPayload" ), mUseExternalPayloadFile ).toBool();
}

DbConfig::~DbConfig()
{
}

DbConfig* DbConfig::configuredDatabase()
{
  if ( !s_DbConfigInstance ) {
    const QString serverConfigFile = XdgBaseDirs::akonadiServerConfigFile( XdgBaseDirs::ReadWrite );
    QSettings settings( serverConfigFile, QSettings::IniFormat );

    // determine driver to use
    const QString defaultDriver = QLatin1String( "QMYSQL" );
    QString driverName = settings.value( QLatin1String( "General/Driver" ), defaultDriver ).toString();
    if ( driverName.isEmpty() )
      driverName = defaultDriver;

    if ( driverName == QLatin1String( "QMYSQL" ) )
      s_DbConfigInstance = new DbConfigMysql;
    else if ( driverName == QLatin1String( "QMYSQL_EMBEDDED" ) )
      s_DbConfigInstance = new DbConfigMysqlEmbedded;
    else if ( driverName == QLatin1String( "QSQLITE" ) )
      s_DbConfigInstance = new DbConfigSqlite( DbConfigSqlite::Default );
    else if ( driverName == QLatin1String( "QSQLITE3" ) )
      s_DbConfigInstance = new DbConfigSqlite( DbConfigSqlite::Custom );
    else if ( driverName == QLatin1String( "QPSQL" ) )
      s_DbConfigInstance = new DbConfigPostgresql;
    else
      akFatal() << "Unknown database driver: " << driverName;
  }

  return s_DbConfigInstance;
}

void DbConfig::startInternalServer()
{
  // do nothing
}

void DbConfig::stopInternalServer()
{
  // do nothing
}

qint64 DbConfig::sizeThreshold() const
{
  return mSizeThreshold;
}

bool DbConfig::useExternalPayloadFile() const
{
  return mUseExternalPayloadFile;
}
<commit_msg>disable the fs backend by default again for now, still contains at least one critical bug<commit_after>/*
    Copyright (c) 2010 Tobias Koenig <tokoe@kde.org>

    This library is free software; you can redistribute it and/or modify it
    under the terms of the GNU Library General Public License as published by
    the Free Software Foundation; either version 2 of the License, or (at your
    option) any later version.

    This library 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 Library General Public
    License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
*/

#include "dbconfig.h"

#include "dbconfigmysql.h"
#include "dbconfigmysqlembedded.h"
#include "dbconfigpostgresql.h"
#include "dbconfigsqlite.h"

#include <akdebug.h>
#include <libs/xdgbasedirs_p.h>

using namespace Akonadi;

//TODO: make me Q_GLOBAL_STATIC
static DbConfig *s_DbConfigInstance = 0;

DbConfig::DbConfig()
{
  const QString serverConfigFile = XdgBaseDirs::akonadiServerConfigFile( XdgBaseDirs::ReadWrite );
  QSettings settings( serverConfigFile, QSettings::IniFormat );

  mSizeThreshold = 4096;
  const QVariant value = settings.value( QLatin1String( "General/SizeThreshold" ), mSizeThreshold );
  if ( value.canConvert<qint64>() )
    mSizeThreshold = value.value<qint64>();
  else
    mSizeThreshold = 0;

  if ( mSizeThreshold < 0 )
    mSizeThreshold = 0;

  mUseExternalPayloadFile = false;
  mUseExternalPayloadFile = settings.value( QLatin1String( "General/ExternalPayload" ), mUseExternalPayloadFile ).toBool();
}

DbConfig::~DbConfig()
{
}

DbConfig* DbConfig::configuredDatabase()
{
  if ( !s_DbConfigInstance ) {
    const QString serverConfigFile = XdgBaseDirs::akonadiServerConfigFile( XdgBaseDirs::ReadWrite );
    QSettings settings( serverConfigFile, QSettings::IniFormat );

    // determine driver to use
    const QString defaultDriver = QLatin1String( "QMYSQL" );
    QString driverName = settings.value( QLatin1String( "General/Driver" ), defaultDriver ).toString();
    if ( driverName.isEmpty() )
      driverName = defaultDriver;

    if ( driverName == QLatin1String( "QMYSQL" ) )
      s_DbConfigInstance = new DbConfigMysql;
    else if ( driverName == QLatin1String( "QMYSQL_EMBEDDED" ) )
      s_DbConfigInstance = new DbConfigMysqlEmbedded;
    else if ( driverName == QLatin1String( "QSQLITE" ) )
      s_DbConfigInstance = new DbConfigSqlite( DbConfigSqlite::Default );
    else if ( driverName == QLatin1String( "QSQLITE3" ) )
      s_DbConfigInstance = new DbConfigSqlite( DbConfigSqlite::Custom );
    else if ( driverName == QLatin1String( "QPSQL" ) )
      s_DbConfigInstance = new DbConfigPostgresql;
    else
      akFatal() << "Unknown database driver: " << driverName;
  }

  return s_DbConfigInstance;
}

void DbConfig::startInternalServer()
{
  // do nothing
}

void DbConfig::stopInternalServer()
{
  // do nothing
}

qint64 DbConfig::sizeThreshold() const
{
  return mSizeThreshold;
}

bool DbConfig::useExternalPayloadFile() const
{
  return mUseExternalPayloadFile;
}
<|endoftext|>


<commit_before>#ifndef SILICIUM_REACTIVE_OBSERVABLE_HPP
#define SILICIUM_REACTIVE_OBSERVABLE_HPP

#include <silicium/observer.hpp>

namespace Si
{
	template <class E>
	struct observable
	{
		typedef E element_type;

		virtual ~observable()
		{
		}

		virtual void async_get_one(observer<element_type> &receiver) = 0;
	};
}

#endif
<commit_msg>create a Boost concept for Observable<commit_after>#ifndef SILICIUM_REACTIVE_OBSERVABLE_HPP
#define SILICIUM_REACTIVE_OBSERVABLE_HPP

#include <silicium/observer.hpp>
#include <silicium/override.hpp>
#include <boost/concept_check.hpp>

namespace Si
{
	template <class E>
	struct observable
	{
		typedef E element_type;

		virtual ~observable()
		{
		}

		virtual void async_get_one(observer<element_type> &receiver) = 0;
	};

	template <class X>
	struct Observable
	{
		using element_type = typename X::element_type;

		BOOST_CONCEPT_USAGE(Observable)
		{
			X moved = std::move(observable);
			moved = std::move(observable);
			observable.async_get_one(observer);
		}

	private:

		struct test_observer : observer<element_type>
		{
			virtual void got_element(element_type) SILICIUM_OVERRIDE
			{
			}

			virtual void ended() SILICIUM_OVERRIDE
			{
			}
		};

		X observable;
		test_observer observer;
		element_type element;
	};

	namespace detail
	{
		//example and test for the smallest possible Observable
		struct minimum_observable
		{
			using element_type = int;
			void async_get_one(observer<element_type> &)
			{
			}
		};

		BOOST_CONCEPT_ASSERT((Observable<minimum_observable>));
	}
}

#endif
<|endoftext|>


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

#ifndef ASMITH_REFLECTION_VARIABLE_HPP
#define ASMITH_REFLECTION_VARIABLE_HPP

#include <cstdint>

namespace asmith {
	class reflection_class;

	class reflection_variable {
	public:
		virtual ~reflection_variable() {}

		virtual const reflection_class& get_class() const = 0;
		virtual const char* get_name() const = 0;
		virtual uint32_t get_modifiers() const = 0;

		virtual void set_(void*, const void*) const = 0;
		virtual void get_(const void*, void*) const = 0;

		template<class CLASS, class T>
		void set(CLASS& aObject, T aValue) const {
			//! \todo Check type
			set_(&aObject, &aValue);
		}

		template<class CLASS, class T>
		T get(const CLASS& aObject, T aValue) const {
			//! \todo Check type
			T tmp;
			get_(&aObject, &tmp);
			return tmp;
		}
	};

	template<class CLASS, class T>
	class auto_reflection_variable : public reflection_variable {
	public:
		typedef T(CLASS::*ptr_t);
	private:
		const std::string mName;
		const ptr_t mPointer;
		const size_t mModifiers;
	protected:
		// Inherited from reflection_variable

		void set_(void* aObject, const void* aValue) const override {
			CLASS& obj = *reinterpret_cast<CLASS*>(aObject);
			const T& val = *reinterpret_cast<const T*>(aValue);
			((obj).*(mPointer)) = val;
		}

		void get_(const void* aObject, void* aValue) const override {
			const CLASS& obj = *reinterpret_cast<const CLASS*>(aObject);
			T& val = *reinterpret_cast<T*>(aValue);
			val = ((obj).*(mPointer));
		}

	public:
		auto_reflection_variable(const std::string& aName, const ptr_t aPtr, const size_t aModifiers) :
			mName(aName),
			mModifiers(aModifiers),
			mPointer(aPtr)
		{}

		// Inherited from reflection_function

		const char* get_name() const override {
			return mName.c_str();
		}

		const reflection_class& get_class() const override {
			return reflect<T>();
		};

		size_t get_modifiers() const override {
			return mModifiers;
		};
	};
}

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

#ifndef ASMITH_REFLECTION_VARIABLE_HPP
#define ASMITH_REFLECTION_VARIABLE_HPP

#include <cstdint>

namespace asmith {
	class reflection_class;

	class reflection_variable {
	public:
		virtual ~reflection_variable() {}

		virtual const reflection_class& get_class() const = 0;
		virtual const char* get_name() const = 0;
		virtual uint32_t get_modifiers() const = 0;

		virtual void set_unsafe(void*, const void*) const = 0;
		virtual void get_unsafe(const void*, void*) const = 0;

		template<class CLASS, class T>
		void set(CLASS& aObject, T aValue) const {
			//! \todo Check type
			set_unsafe(&aObject, &aValue);
		}

		template<class CLASS, class T>
		T get(const CLASS& aObject, T aValue) const {
			//! \todo Check type
			T tmp;
			get_unsafe(&aObject, &tmp);
			return tmp;
		}
	};

	template<class CLASS, class T>
	class auto_reflection_variable : public reflection_variable {
	public:
		typedef T(CLASS::*ptr_t);
	private:
		const std::string mName;
		const ptr_t mPointer;
		const size_t mModifiers;
	protected:
		// Inherited from reflection_variable

		void set_unsafe(void* aObject, const void* aValue) const override {
			CLASS& obj = *reinterpret_cast<CLASS*>(aObject);
			const T& val = *reinterpret_cast<const T*>(aValue);
			((obj).*(mPointer)) = val;
		}

		void get_unsafe(const void* aObject, void* aValue) const override {
			const CLASS& obj = *reinterpret_cast<const CLASS*>(aObject);
			T& val = *reinterpret_cast<T*>(aValue);
			val = ((obj).*(mPointer));
		}

	public:
		auto_reflection_variable(const std::string& aName, const ptr_t aPtr, const size_t aModifiers) :
			mName(aName),
			mModifiers(aModifiers),
			mPointer(aPtr)
		{}

		// Inherited from reflection_function

		const char* get_name() const override {
			return mName.c_str();
		}

		const reflection_class& get_class() const override {
			return reflect<T>();
		};

		size_t get_modifiers() const override {
			return mModifiers;
		};
	};
}

#endif<|endoftext|>


<commit_before>#pragma once
#ifndef NIFTY_GRAPH_OPTIMIZATION_VISITOR_BASE_HXX
#define NIFTY_GRAPH_OPTIMIZATION_VISITOR_BASE_HXX

#include <string>
#include <initializer_list>
#include <sstream>
#include <iostream>
#include <chrono>

namespace nifty {
namespace graph {
namespace optimization{

    template<class SOLVER>
    class VisitorBase{
    public:

        typedef SOLVER SolverType;

        // maybe the solver ptr will become a shared ptr
        virtual void begin(SolverType * solver) = 0;
        virtual bool visit(SolverType * solver) = 0;
        virtual void end(SolverType * solver) = 0;

        virtual void addLogNames(std::initializer_list<std::string> logNames){

        }
        virtual void setLogValue(const size_t logIndex, double logValue){

        }
    };

    template<class SOLVER>
    class VerboseVisitor : public VisitorBase<SOLVER>{
    public:
        typedef SOLVER SolverType;
        typedef std::chrono::seconds TimeType;
        typedef std::chrono::time_point<std::chrono::steady_clock> TimePointType;

        VerboseVisitor(const int printNth = 1, const size_t timeLimit = 0)
        :   printNth_(printNth),
            runOpt_(true),
            iter_(1),
            timeLimit_(timeLimit){
        }

        virtual void begin(SolverType * ) {
            std::cout<<"begin inference\n";
            startTime_ = std::chrono::steady_clock::now();
        }

        virtual bool visit(SolverType * solver) {
            if(iter_%printNth_ == 0){
                std::stringstream ss;
                ss<<solver->currentBestEnergy()<<" ";
                for(size_t i=0; i<logNames_.size(); ++i){
                    ss<<logNames_[i]<<" "<<logValues_[i]<<" ";
                }
                ss<<"\n";
                std::cout<<ss.str();
            }
            if(timeLimit_ > 0)
                checkRuntime();
            ++iter_;
            return runOpt_;
        }

        virtual void end(SolverType * )   {
            std::cout<<"end inference\n";
        }

        virtual void addLogNames(std::initializer_list<std::string> logNames){
            logNames_.assign(logNames.begin(), logNames.end());
            logValues_.resize(logNames.size());
        }

        virtual void setLogValue(const size_t logIndex, double logValue){
            logValues_[logIndex] = logValue;
        }

        void stopOptimize(){
            runOpt_ = false;
        }

    private:
        bool runOpt_;
        int printNth_;
        int iter_;
        size_t timeLimit_;
        TimePointType startTime_;

        std::vector<std::string> logNames_;
        std::vector<double> logValues_;

        inline void checkRuntime() {
            auto runtime = std::chrono::duration_cast<TimeType>(
                    std::chrono::steady_clock::now() - startTime_);
            if(runtime.count() < timeLimit_) {
                std::cout << "Inference has exceeded time limit and is stopped \n";
                stopOptimize();
            }
        }
    };

    template<class SOLVER>
    class EmptyVisitor : public VisitorBase<SOLVER>{
    public:
        typedef SOLVER SolverType;

        virtual void begin(SolverType * solver) {}
        virtual bool visit(SolverType * solver) {return true;}
        virtual void end(SolverType * solver)   {}
    private:
    };

    template<class SOLVER>
    class VisitorProxy{
    public:
        typedef SOLVER SolverType;
        typedef VisitorBase<SOLVER> VisitorBaseTpe;
        VisitorProxy(VisitorBaseTpe * visitor)
        :   visitor_(visitor){

        }

        void addLogNames(std::initializer_list<std::string> logNames){
            if(visitor_  != nullptr){
                visitor_->addLogNames(logNames);
            }
        }
        void begin(SolverType * solver) {
            if(visitor_ != nullptr){
                visitor_->begin(solver);
            }
        }
        bool visit(SolverType * solver) {
            if(visitor_ != nullptr){
                return visitor_->visit(solver);
            }
            return true;
        }
        void end(SolverType * solver)   {
            if(visitor_ != nullptr){
                visitor_->begin(solver);
            }
        }

        void setLogValue(const size_t logIndex, const double logValue)   {
            if(visitor_ != nullptr){
                visitor_->setLogValue(logIndex, logValue);
            }
        }

    private:
        VisitorBaseTpe * visitor_;
    };

}
}
}

#endif // NIFTY_GRAPH_OPTIMIZATION_VISITOR_BASE_HXX
<commit_msg>Fix time comparison in visitor<commit_after>#pragma once
#ifndef NIFTY_GRAPH_OPTIMIZATION_VISITOR_BASE_HXX
#define NIFTY_GRAPH_OPTIMIZATION_VISITOR_BASE_HXX

#include <string>
#include <initializer_list>
#include <sstream>
#include <iostream>
#include <chrono>

namespace nifty {
namespace graph {
namespace optimization{

    template<class SOLVER>
    class VisitorBase{
    public:

        typedef SOLVER SolverType;

        // maybe the solver ptr will become a shared ptr
        virtual void begin(SolverType * solver) = 0;
        virtual bool visit(SolverType * solver) = 0;
        virtual void end(SolverType * solver) = 0;

        virtual void addLogNames(std::initializer_list<std::string> logNames){

        }
        virtual void setLogValue(const size_t logIndex, double logValue){

        }
    };

    template<class SOLVER>
    class VerboseVisitor : public VisitorBase<SOLVER>{
    public:
        typedef SOLVER SolverType;
        typedef std::chrono::seconds TimeType;
        typedef std::chrono::time_point<std::chrono::steady_clock> TimePointType;

        VerboseVisitor(const int printNth = 1, const size_t timeLimit = 0)
        :   printNth_(printNth),
            runOpt_(true),
            iter_(1),
            timeLimit_(timeLimit){
        }

        virtual void begin(SolverType * ) {
            std::cout<<"begin inference\n";
            if(timeLimit_ > 0) {
                std::cout << "With Time Limit: \n";
                std::cout << timeLimit_ << std::endl;
            }
            startTime_ = std::chrono::steady_clock::now();
        }

        virtual bool visit(SolverType * solver) {
            if(iter_%printNth_ == 0){
                std::stringstream ss;
                ss<<solver->currentBestEnergy()<<" ";
                for(size_t i=0; i<logNames_.size(); ++i){
                    ss<<logNames_[i]<<" "<<logValues_[i]<<" ";
                }
                ss<<"\n";
                std::cout<<ss.str();
            }
            if(timeLimit_ > 0)
                checkRuntime();
            ++iter_;
            return runOpt_;
        }

        virtual void end(SolverType * )   {
            std::cout<<"end inference\n";
        }

        virtual void addLogNames(std::initializer_list<std::string> logNames){
            logNames_.assign(logNames.begin(), logNames.end());
            logValues_.resize(logNames.size());
        }

        virtual void setLogValue(const size_t logIndex, double logValue){
            logValues_[logIndex] = logValue;
        }

        void stopOptimize(){
            runOpt_ = false;
        }

    private:
        bool runOpt_;
        int printNth_;
        int iter_;
        size_t timeLimit_;
        TimePointType startTime_;

        std::vector<std::string> logNames_;
        std::vector<double> logValues_;

        inline void checkRuntime() {
            auto runtime = std::chrono::duration_cast<TimeType>(
                    std::chrono::steady_clock::now() - startTime_);
            if(runtime.count() > timeLimit_) {
                std::cout << "Inference has exceeded time limit and is stopped \n";
                stopOptimize();
            }
        }
    };

    template<class SOLVER>
    class EmptyVisitor : public VisitorBase<SOLVER>{
    public:
        typedef SOLVER SolverType;

        virtual void begin(SolverType * solver) {}
        virtual bool visit(SolverType * solver) {return true;}
        virtual void end(SolverType * solver)   {}
    private:
    };

    template<class SOLVER>
    class VisitorProxy{
    public:
        typedef SOLVER SolverType;
        typedef VisitorBase<SOLVER> VisitorBaseTpe;
        VisitorProxy(VisitorBaseTpe * visitor)
        :   visitor_(visitor){

        }

        void addLogNames(std::initializer_list<std::string> logNames){
            if(visitor_  != nullptr){
                visitor_->addLogNames(logNames);
            }
        }
        void begin(SolverType * solver) {
            if(visitor_ != nullptr){
                visitor_->begin(solver);
            }
        }
        bool visit(SolverType * solver) {
            if(visitor_ != nullptr){
                return visitor_->visit(solver);
            }
            return true;
        }
        void end(SolverType * solver)   {
            if(visitor_ != nullptr){
                visitor_->begin(solver);
            }
        }

        void setLogValue(const size_t logIndex, const double logValue)   {
            if(visitor_ != nullptr){
                visitor_->setLogValue(logIndex, logValue);
            }
        }

    private:
        VisitorBaseTpe * visitor_;
    };

}
}
}

#endif // NIFTY_GRAPH_OPTIMIZATION_VISITOR_BASE_HXX
<|endoftext|>


<commit_before>#include <iostream>
#include <iomanip>
#include <fstream>
#include "boost/program_options.hpp"
#include "multisnake.h"
#include "utility.h"

/*
 * Evaluate the resultant snakes using Vertex Error and Hausdorff
 * Distance if the ground truths are known and using F-function
 * otherwise.
 */

int main(int argc, char **argv) {
  namespace po = boost::program_options;
  po::options_description generic("Generic options");
  generic.add_options()
      ("version,v", "Print version and exit")
      ("help,h", "Print help message and exit")
      ;
  std::string snake_path, function_path;
  po::options_description required("Required options");
  required.add_options()
      ("snake,s", po::value<std::string>(&snake_path)->required(),
       "Snake file path")
      ("function,f",
       po::value<std::string>(&function_path)->required(),
       "Evaluation function output file path")
      ;

  std::string comparing_snake_path;
  double snr_threshold(0.0);
  double penalizer(0.0);

  po::options_description optional("Optional options");
  optional.add_options()
      ("comparing,c",
       po::value<std::string>(&comparing_snake_path)->required(),
       "Comparing snake file path")
      ("snr,t", po::value<double>(&snr_threshold)->required(),
       "Low SNR threshold")
      ("penalizer,p", po::value<double>(&penalizer)->required(),
       "Constant c for penalizing the low SNR snake points.")
      ("grad-diff", "Set grad-diff as a variable")
      ("stretch", "Set stretch as a variable")
      ;

  po::options_description all("Allowed options");
  all.add(generic).add(required).add(optional);

  po::variables_map vm;
  po::store(parse_command_line(argc, argv, all), vm);

  if (vm.count("version")) {
    std::cout << "SOAX Evaluation 1.3\n"
        "Copyright (C) 2013 Ting Xu, IDEA Lab, Lehigh University."
              << std::endl;
    return EXIT_SUCCESS;
  }

  if (vm.count("help")) {
    std::cout << "Usage for SOAX Evaluation: \n";
    std::cout << all;
    return EXIT_SUCCESS;
  }

  po::notify(vm);
  soax::Multisnake multisnake;
  multisnake.LoadImage(soax::GetImagePath(snake_path));
  multisnake.LoadConvergedSnakes(snake_path);

  if (vm.count("comparing")) {
    multisnake.LoadGroundTruthSnakes(comparing_snake_path);
    multisnake.EvaluateByVertexErrorHausdorffDistance(snake_path,
                                                      function_path);
  } else {
    multisnake.EvaluateByFFunction(snr_threshold, penalizer,
                                   snake_path, function_path);
  }

  return EXIT_SUCCESS;
}
<commit_msg>add try/catch for evaluate.cc<commit_after>#include <iostream>
#include <iomanip>
#include <fstream>
#include "boost/program_options.hpp"
#include "multisnake.h"
#include "utility.h"

/*
 * Evaluate the resultant snakes using Vertex Error and Hausdorff
 * Distance if the ground truths are known and using F-function
 * otherwise.
 */

int main(int argc, char **argv) {
  try {
    namespace po = boost::program_options;
    po::options_description generic("Generic options");
    generic.add_options()
        ("version,v", "Print version and exit")
        ("help,h", "Print help message and exit")
        ;
    std::string snake_path, function_path;
    po::options_description required("Required options");
    required.add_options()
        ("snake,s", po::value<std::string>(&snake_path)->required(),
         "Snake file path")
        ("function,f",
         po::value<std::string>(&function_path)->required(),
         "Evaluation function output file path")
        ;

    std::string comparing_snake_path;
    double snr_threshold(0.0);
    double penalizer(0.0);

    po::options_description optional("Optional options");
    optional.add_options()
        ("comparing,c",
         po::value<std::string>(&comparing_snake_path)->required(),
         "Comparing snake file path")
        ("snr,t", po::value<double>(&snr_threshold)->required(),
         "Low SNR threshold")
        ("penalizer,p", po::value<double>(&penalizer)->required(),
         "Constant c for penalizing the low SNR snake points.")
        // ("grad-diff", "Set grad-diff as a variable")
        // ("stretch", "Set stretch as a variable")
        ;

    po::options_description all("Allowed options");
    all.add(generic).add(required).add(optional);

    po::variables_map vm;
    po::store(parse_command_line(argc, argv, all), vm);

    if (vm.count("version")) {
      std::cout << "SOAX Evaluation 1.3\n"
          "Copyright (C) 2013 Ting Xu, IDEA Lab, Lehigh University."
                << std::endl;
      return EXIT_SUCCESS;
    }

    if (vm.count("help")) {
      std::cout << "Usage for SOAX Evaluation: \n";
      std::cout << all;
      return EXIT_SUCCESS;
    }

    po::notify(vm);
    soax::Multisnake multisnake;
    multisnake.LoadImage(soax::GetImagePath(snake_path));
    multisnake.LoadConvergedSnakes(snake_path);

    if (vm.count("comparing")) {
      multisnake.LoadGroundTruthSnakes(comparing_snake_path);
      multisnake.EvaluateByVertexErrorHausdorffDistance(snake_path,
                                                        function_path);
    } else {
      multisnake.EvaluateByFFunction(snr_threshold, penalizer,
                                     snake_path, function_path);
    }
  } catch (std::exception &e) {
    std::cout << e.what() << std::endl;
    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/*
 */
#ifndef COMMON_HPP_INCLUDED
#define COMMON_HPP_INCLUDED

#include <iostream>
#include <vector>
#include <map>
#include <cassert>
#include <sstream>
#include <memory>

#define FMT(ss)    (dynamic_cast< ::std::stringstream&>(::std::stringstream() << ss).str())
// XXX: Evil hack - Define 'mv$' to be ::std::move
#define mv$(x)    ::std::move(x)
#define box$(x) ::make_unique_ptr(::std::move(x))
#define rc_new$(x) ::make_shared_ptr(::std::move(x))

#include "include/debug.hpp"
#include "include/rustic.hpp"	// slice and option
#include "include/compile_error.hpp"

template<typename T>
::std::unique_ptr<T> make_unique_ptr(T&& v) {
    return ::std::unique_ptr<T>(new T(mv$(v)));
}
template<typename T>
::std::shared_ptr<T> make_shared_ptr(T&& v) {
    return ::std::shared_ptr<T>(new T(mv$(v)));
}
template<typename T>
::std::vector<T> make_vec1(T&& v) {
    ::std::vector<T>    rv;
    rv.push_back( mv$(v) );
    return rv;
}

enum Ordering
{
    OrdLess,
    OrdEqual,
    OrdGreater,
};
static inline Ordering ord(bool l, bool r)
{
    if(l == r)
        return OrdEqual;
    else if( l )
        return OrdGreater;
    else
        return OrdLess;
}
static inline Ordering ord(unsigned l, unsigned r)
{
    if(l == r)
        return OrdEqual;
    else if( l > r )
        return OrdGreater;
    else
        return OrdLess;
}
static inline Ordering ord(::std::uintptr_t l, ::std::uintptr_t r)
{
    if(l == r)
        return OrdEqual;
    else if( l > r )
        return OrdGreater;
    else
        return OrdLess;
}
static inline Ordering ord(const ::std::string& l, const ::std::string& r)
{
    if(l == r)
        return OrdEqual;
    else if( l > r )
        return OrdGreater;
    else
        return OrdLess;
}
template<typename T>
Ordering ord(const T& l, const T& r)
{
    return l.ord(r);
}
template<typename T, typename U>
Ordering ord(const ::std::pair<T,U>& l, const ::std::pair<T,U>& r)
{
    Ordering    rv;
    rv = ::ord(l.first, r.first);
    if(rv != OrdEqual)   return rv;
    rv = ::ord(l.second, r.second);
    return rv;
}
template<typename T>
Ordering ord(const ::std::vector<T>& l, const ::std::vector<T>& r)
{
    unsigned int i = 0;
    for(const auto& it : l)
    {
        if( i >= r.size() )
            return OrdGreater;

        auto rv = ::ord( it, r[i] );
        if( rv != OrdEqual )
            return rv;

        i ++;
    }

    return OrdEqual;
}
template<typename T, typename U>
Ordering ord(const ::std::map<T,U>& l, const ::std::map<T,U>& r)
{
    auto r_it = r.begin();
    for(const auto& le : l)
    {
        if( r_it == r.end() )
            return OrdGreater;
        auto rv = ::ord( le, *r_it );
        if( rv != OrdEqual )
            return rv;
        ++ r_it;
    }
    return OrdEqual;
}
#define ORD(a,b)    do { Ordering ORD_rv = ::ord(a,b); if( ORD_rv != ::OrdEqual )   return ORD_rv; } while(0)

template <typename T>
struct LList
{
    const LList*  m_prev;
    T   m_item;

    LList(const LList* prev, T item):
        m_prev(prev),
        m_item( ::std::move(item) )
    {
    };
};

template<typename T>
struct Join {
    const char *sep;
    const ::std::vector<T>& v;
    friend ::std::ostream& operator<<(::std::ostream& os, const Join& j) {
        if( j.v.size() > 0 )
            os << j.v[0];
        for( unsigned int i = 1; i < j.v.size(); i ++ )
            os << j.sep << j.v[i];
        return os;
    }
};
template<typename T>
inline Join<T> join(const char *sep, const ::std::vector<T> v) {
    return Join<T>({ sep, v });
}

namespace std {

template <typename T>
inline ::std::ostream& operator<<(::std::ostream& os, const ::std::vector<T*>& v) {
    if( v.size() > 0 )
    {
        bool is_first = true;
        for( const auto& i : v )
        {
            if(!is_first)
                os << ", ";
            is_first = false;
            os << *i;
        }
    }
    return os;
}

template <typename T>
inline ::std::ostream& operator<<(::std::ostream& os, const ::std::vector<T>& v) {
    if( v.size() > 0 )
    {
        bool is_first = true;
        for( const auto& i : v )
        {
            if(!is_first)
                os << ", ";
            is_first = false;
            os << i;
        }
    }
    return os;
}

template <typename T, typename U>
inline ::std::ostream& operator<<(::std::ostream& os, const ::std::pair<T,U>& v) {
    os << "(" << v.first << ", " << v.second << ")";
    return os;
}

template <typename T, typename U, class Cmp>
inline ::std::ostream& operator<<(::std::ostream& os, const ::std::map<T,U,Cmp>& v) {
    if( v.size() > 0 )
    {
        bool is_first = true;
        for( const auto& i : v )
        {
            if(!is_first)
                os << ", ";
            is_first = false;
            os << i.first << ": " << i.second;
        }
    }
    return os;
}

template <typename T, typename U, class Cmp>
inline ::std::ostream& operator<<(::std::ostream& os, const ::std::multimap<T,U,Cmp>& v) {
    if( v.size() > 0 )
    {
        bool is_first = true;
        for( const auto& i : v )
        {
            if(!is_first)
                os << ", ";
            is_first = false;
            os << i.first << ": " << i.second;
        }
    }
    return os;
}

}

// -------------------------------------------------------------------
// --- Reversed iterable
template <typename T>
struct reversion_wrapper { T& iterable; };

template <typename T>
//auto begin (reversion_wrapper<T> w) { return ::std::rbegin(w.iterable); }
auto begin (reversion_wrapper<T> w) { return w.iterable.rbegin(); }

template <typename T>
//auto end (reversion_wrapper<T> w) { return ::std::rend(w.iterable); }
auto end (reversion_wrapper<T> w) { return w.iterable.rend(); }

template <typename T>
reversion_wrapper<T> reverse (T&& iterable) { return { iterable }; }

#endif
<commit_msg>Common - Useful helper for some of the typecheck changes<commit_after>/*
 */
#ifndef COMMON_HPP_INCLUDED
#define COMMON_HPP_INCLUDED

#include <iostream>
#include <vector>
#include <map>
#include <cassert>
#include <sstream>
#include <memory>

#define FMT(ss)    (dynamic_cast< ::std::stringstream&>(::std::stringstream() << ss).str())
// XXX: Evil hack - Define 'mv$' to be ::std::move
#define mv$(x)    ::std::move(x)
#define box$(x) ::make_unique_ptr(::std::move(x))
#define rc_new$(x) ::make_shared_ptr(::std::move(x))

#include "include/debug.hpp"
#include "include/rustic.hpp"	// slice and option
#include "include/compile_error.hpp"

template<typename T>
::std::unique_ptr<T> make_unique_ptr(T&& v) {
    return ::std::unique_ptr<T>(new T(mv$(v)));
}
template<typename T>
::std::shared_ptr<T> make_shared_ptr(T&& v) {
    return ::std::shared_ptr<T>(new T(mv$(v)));
}
template<typename T>
::std::vector<T> make_vec1(T&& v) {
    ::std::vector<T>    rv;
    rv.push_back( mv$(v) );
    return rv;
}

enum Ordering
{
    OrdLess,
    OrdEqual,
    OrdGreater,
};
static inline Ordering ord(bool l, bool r)
{
    if(l == r)
        return OrdEqual;
    else if( l )
        return OrdGreater;
    else
        return OrdLess;
}
static inline Ordering ord(unsigned l, unsigned r)
{
    if(l == r)
        return OrdEqual;
    else if( l > r )
        return OrdGreater;
    else
        return OrdLess;
}
static inline Ordering ord(::std::uintptr_t l, ::std::uintptr_t r)
{
    if(l == r)
        return OrdEqual;
    else if( l > r )
        return OrdGreater;
    else
        return OrdLess;
}
static inline Ordering ord(const ::std::string& l, const ::std::string& r)
{
    if(l == r)
        return OrdEqual;
    else if( l > r )
        return OrdGreater;
    else
        return OrdLess;
}
template<typename T>
Ordering ord(const T& l, const T& r)
{
    return l.ord(r);
}
template<typename T, typename U>
Ordering ord(const ::std::pair<T,U>& l, const ::std::pair<T,U>& r)
{
    Ordering    rv;
    rv = ::ord(l.first, r.first);
    if(rv != OrdEqual)   return rv;
    rv = ::ord(l.second, r.second);
    return rv;
}
template<typename T>
Ordering ord(const ::std::vector<T>& l, const ::std::vector<T>& r)
{
    unsigned int i = 0;
    for(const auto& it : l)
    {
        if( i >= r.size() )
            return OrdGreater;

        auto rv = ::ord( it, r[i] );
        if( rv != OrdEqual )
            return rv;

        i ++;
    }

    return OrdEqual;
}
template<typename T, typename U>
Ordering ord(const ::std::map<T,U>& l, const ::std::map<T,U>& r)
{
    auto r_it = r.begin();
    for(const auto& le : l)
    {
        if( r_it == r.end() )
            return OrdGreater;
        auto rv = ::ord( le, *r_it );
        if( rv != OrdEqual )
            return rv;
        ++ r_it;
    }
    return OrdEqual;
}
#define ORD(a,b)    do { Ordering ORD_rv = ::ord(a,b); if( ORD_rv != ::OrdEqual )   return ORD_rv; } while(0)

template <typename T>
struct LList
{
    const LList*  m_prev;
    T   m_item;

    LList():
        m_prev(nullptr)
    {}
    LList(const LList* prev, T item):
        m_prev(prev),
        m_item( ::std::move(item) )
    {
    }

    LList end() const {
        return LList();
    }
    LList begin() const {
        return *this;
    }
    bool operator==(const LList& x) {
        return m_prev == x.m_prev;
    }
    bool operator!=(const LList& x) {
        return m_prev != x.m_prev;
    }
    void operator++() {
        assert(m_prev);
        *this = *m_prev;
    }
    const T& operator*() const {
        return m_item;
    }
};

template<typename T>
struct Join {
    const char *sep;
    const ::std::vector<T>& v;
    friend ::std::ostream& operator<<(::std::ostream& os, const Join& j) {
        if( j.v.size() > 0 )
            os << j.v[0];
        for( unsigned int i = 1; i < j.v.size(); i ++ )
            os << j.sep << j.v[i];
        return os;
    }
};
template<typename T>
inline Join<T> join(const char *sep, const ::std::vector<T> v) {
    return Join<T>({ sep, v });
}

namespace std {

template <typename T>
inline ::std::ostream& operator<<(::std::ostream& os, const ::std::vector<T*>& v) {
    if( v.size() > 0 )
    {
        bool is_first = true;
        for( const auto& i : v )
        {
            if(!is_first)
                os << ", ";
            is_first = false;
            os << *i;
        }
    }
    return os;
}

template <typename T>
inline ::std::ostream& operator<<(::std::ostream& os, const ::std::vector<T>& v) {
    if( v.size() > 0 )
    {
        bool is_first = true;
        for( const auto& i : v )
        {
            if(!is_first)
                os << ", ";
            is_first = false;
            os << i;
        }
    }
    return os;
}

template <typename T, typename U>
inline ::std::ostream& operator<<(::std::ostream& os, const ::std::pair<T,U>& v) {
    os << "(" << v.first << ", " << v.second << ")";
    return os;
}

template <typename T, typename U, class Cmp>
inline ::std::ostream& operator<<(::std::ostream& os, const ::std::map<T,U,Cmp>& v) {
    if( v.size() > 0 )
    {
        bool is_first = true;
        for( const auto& i : v )
        {
            if(!is_first)
                os << ", ";
            is_first = false;
            os << i.first << ": " << i.second;
        }
    }
    return os;
}

template <typename T, typename U, class Cmp>
inline ::std::ostream& operator<<(::std::ostream& os, const ::std::multimap<T,U,Cmp>& v) {
    if( v.size() > 0 )
    {
        bool is_first = true;
        for( const auto& i : v )
        {
            if(!is_first)
                os << ", ";
            is_first = false;
            os << i.first << ": " << i.second;
        }
    }
    return os;
}

}

// -------------------------------------------------------------------
// --- Reversed iterable
template <typename T>
struct reversion_wrapper { T& iterable; };

template <typename T>
//auto begin (reversion_wrapper<T> w) { return ::std::rbegin(w.iterable); }
auto begin (reversion_wrapper<T> w) { return w.iterable.rbegin(); }

template <typename T>
//auto end (reversion_wrapper<T> w) { return ::std::rend(w.iterable); }
auto end (reversion_wrapper<T> w) { return w.iterable.rend(); }

template <typename T>
reversion_wrapper<T> reverse (T&& iterable) { return { iterable }; }

#endif
<|endoftext|>


<commit_before>#include "memory.hpp"

namespace {

struct bios_mmap_entry {
    uint32_t base_low;
    uint32_t base_high;
    uint32_t length_low;
    uint32_t length_high;
    uint16_t type;
    uint16_t acpi;
    uint32_t damn_padding;
} __attribute__((packed));

uint64_t e820_failed = 0;
uint64_t entry_count = 0;
bios_mmap_entry* e820_address = 0;

mmapentry e820_mmap[32];

void mmap_query(uint64_t cmd, uint64_t* result){
    uint64_t tmp;
    __asm__ __volatile__ ("mov r8, %0; int 62; mov %1, rax" : : "dN" (cmd), "a" (tmp));
    *result = tmp;
}

uint64_t _available_memory;
uint64_t _used_memory;

struct malloc_header_chunk {
    uint64_t size;
    malloc_header_chunk* next;
    malloc_header_chunk* prev;
};

struct malloc_footer_chunk {
    uint64_t size;
};

struct fake_head {
    uint64_t size;
    malloc_header_chunk* next;
    malloc_header_chunk* prev;
    uint64_t size_2;
};

const uint64_t META_SIZE = sizeof(malloc_header_chunk) + sizeof(malloc_footer_chunk);
const uint64_t MIN_SPLIT = 32;
const uint64_t BLOCK_SIZE = 4096;
const uint64_t MIN_BLOCKS = 4;

fake_head head;
malloc_header_chunk* malloc_head = 0;

typedef uint64_t* page_entry;
typedef page_entry* pt_t;
typedef pt_t* pdt_t;
typedef pdt_t* pdpt_t;
typedef pdpt_t* pml4t_t;

mmapentry* current_mmap_entry = nullptr;
uint64_t current_mmap_entry_position;

uint64_t pml4t_index = 0;
uint64_t pdpt_index = 0;
uint64_t pdt_index = 0;
uint64_t pt_index = 256;

uint64_t* allocate_block(uint64_t blocks){
    if(!current_mmap_entry){
        for(uint64_t i = 0; i < entry_count; ++i){
            auto& entry = e820_mmap[i];

            if(entry.type == 1 && entry.base >= 0x100000 && entry.size >= 16384){
                current_mmap_entry = &entry;
                current_mmap_entry_position = entry.base;
                break;
            }
        }
    }

    if(!current_mmap_entry){
        return nullptr;
    }

    pml4t_t pml4t = reinterpret_cast<pml4t_t>(0x70000);
    auto pdpt = reinterpret_cast<pdpt_t>(reinterpret_cast<uintptr_t>(pml4t[pml4t_index]) & ~0xFFF);
    auto pdt = reinterpret_cast<pdt_t>(reinterpret_cast<uintptr_t>(pdpt[pdpt_index]) & ~0xFFF);
    auto pt = reinterpret_cast<pt_t>(reinterpret_cast<uintptr_t>(pdt[pdt_index]) & ~0xFFF);

    if(pt_index + blocks >= 512){
        //TODO Go to a new page table
    }

    for(uint64_t i = 0; i < blocks; ++i){
        pt[pt_index + i] = reinterpret_cast<page_entry>((current_mmap_entry_position + i * BLOCK_SIZE) | 0x3);
    }

    auto block = reinterpret_cast<uint64_t*>(current_mmap_entry_position);

    pt_index += blocks;
    current_mmap_entry_position += blocks * BLOCK_SIZE;

    return block;
}

} //end of anonymous namespace

void init_memory_manager(){
    //Init the fake head
    head.size = 0;
    head.next = nullptr;
    head.prev = nullptr;
    head.size_2 = 0;

    malloc_head = reinterpret_cast<malloc_header_chunk*>(&head);

    auto block = allocate_block(MIN_BLOCKS);
    auto header = reinterpret_cast<malloc_header_chunk*>(block);

    header->size = MIN_BLOCKS * BLOCK_SIZE - META_SIZE;
    header->next = malloc_head;
    header->prev = malloc_head;

    auto footer = reinterpret_cast<malloc_footer_chunk*>(
        reinterpret_cast<uintptr_t>(block) + header->size + sizeof(malloc_header_chunk));
    footer->size = header->size;

    malloc_head->next = header;
    malloc_head->prev = header;
}

uint64_t* k_malloc(uint64_t bytes){
    auto current = malloc_head->next;

    while(true){
        if(current == malloc_head){
            //There are no blocks big enough to hold this request

            uint64_t* block = allocate_block(MIN_BLOCKS);
            auto header = reinterpret_cast<malloc_header_chunk*>(block);
            header->size = MIN_BLOCKS * BLOCK_SIZE - META_SIZE;

            current->next->prev = header;
            current->next = header;

            header->next  = current->next;
            header->prev = current;

            auto footer = reinterpret_cast<malloc_footer_chunk*>(
                reinterpret_cast<uintptr_t>(block) + header->size + sizeof(malloc_header_chunk));
            footer->size = header->size;
        } else if(current->size >= bytes){
            //This block is big enough

            //Is it worth splitting the block ?
            if(current->size - bytes - META_SIZE > MIN_SPLIT){
                auto new_block_size = current->size - bytes - META_SIZE;

                //Set the new size;
                current->size = bytes;

                auto footer = reinterpret_cast<malloc_footer_chunk*>(
                    reinterpret_cast<uintptr_t>(current) + bytes + sizeof(malloc_header_chunk));
                footer->size = bytes;

                auto new_block = reinterpret_cast<malloc_header_chunk*>(
                    reinterpret_cast<uintptr_t>(current) + bytes + META_SIZE);

                new_block->size = new_block_size;
                new_block->next = current->next;
                new_block->prev = current->prev;
                current->prev->next = new_block;
                current->next->prev = new_block;

                auto new_footer = reinterpret_cast<malloc_footer_chunk*>(
                    reinterpret_cast<uintptr_t>(new_block) + new_block_size + sizeof(malloc_header_chunk));
                new_footer->size = new_block_size;

                break;
            } else {
                //Remove this node from the free list
                current->prev->next = current->next;
                current->next->prev = current->prev;

                break;
            }
        }

        current = current->next;
    }

    _used_memory += bytes + META_SIZE;

    //Make sure the node is clean
    current->prev = nullptr;
    current->next = nullptr;

    return reinterpret_cast<uint64_t*>(
        reinterpret_cast<uintptr_t>(current) + sizeof(malloc_header_chunk));
}

void k_free(uint64_t* block){
    auto free_header = reinterpret_cast<malloc_header_chunk*>(
        reinterpret_cast<uintptr_t>(block) - sizeof(malloc_header_chunk));

    _used_memory -= free_header->size + META_SIZE;

    auto header = malloc_head;

    free_header->prev = header;
    free_header->next = header->next;

    header->next->prev = free_header;
    header->next = free_header;
}

void load_memory_map(){
    mmap_query(0, &e820_failed);
    mmap_query(1, &entry_count);
    mmap_query(2, reinterpret_cast<uint64_t*>(&e820_address));

    if(!e820_failed && e820_address){
        for(uint64_t i = 0; i < entry_count; ++i){
            auto& bios_entry = e820_address[i];
            auto& os_entry = e820_mmap[i];

            uint64_t base = bios_entry.base_low + (static_cast<uint64_t>(bios_entry.base_high) << 32);
            uint64_t length = bios_entry.length_low + (static_cast<uint64_t>(bios_entry.length_high) << 32);

            os_entry.base = base;
            os_entry.size = length;
            os_entry.type = bios_entry.type;

            if(os_entry.base == 0 && os_entry.type == 1){
                os_entry.type = 7;
            }

            if(os_entry.type == 1){
                _available_memory += os_entry.size;
            }
        }
    }
}

uint64_t mmap_entry_count(){
    return entry_count;
}

bool mmap_failed(){
    return e820_failed;
}

const mmapentry& mmap_entry(uint64_t i){
    return e820_mmap[i];
}

const char* str_e820_type(uint64_t type){
    switch(type){
        case 1:
            return "Free";
        case 2:
            return "Reserved";
        case 3:
        case 4:
            return "ACPI";
        case 5:
            return "Unusable";
        case 6:
            return "Disabled";
        case 7:
            return "Kernel";
        default:
            return "Unknown";
    }
}

uint64_t available_memory(){
    return _available_memory;
}

uint64_t used_memory(){
    return _used_memory;
}

uint64_t free_memory(){
    return _available_memory - _used_memory;
}
<commit_msg>Fix e820 mmap<commit_after>#include "memory.hpp"
#include "console.hpp"

namespace {

struct bios_mmap_entry {
    uint32_t base_low;
    uint32_t base_high;
    uint32_t length_low;
    uint32_t length_high;
    uint16_t type;
    uint16_t acpi;
    uint32_t damn_padding;
} __attribute__((packed));

uint64_t e820_failed = 0;
uint64_t entry_count = 0;
bios_mmap_entry* e820_address = 0;

mmapentry e820_mmap[32];

void mmap_query(uint64_t cmd, uint64_t* result){
    uint64_t tmp;

    __asm__ __volatile__ ("mov r8, %[port]; int 62; mov %[dst], rax"
        : [dst] "=a" (tmp)
        : [port] "dN" (cmd)
        : "cc", "memory", "r8");

    *result = tmp;
}

uint64_t _available_memory;
uint64_t _used_memory;

struct malloc_header_chunk {
    uint64_t size;
    malloc_header_chunk* next;
    malloc_header_chunk* prev;
};

struct malloc_footer_chunk {
    uint64_t size;
};

struct fake_head {
    uint64_t size;
    malloc_header_chunk* next;
    malloc_header_chunk* prev;
    uint64_t size_2;
};

const uint64_t META_SIZE = sizeof(malloc_header_chunk) + sizeof(malloc_footer_chunk);
const uint64_t MIN_SPLIT = 32;
const uint64_t BLOCK_SIZE = 4096;
const uint64_t MIN_BLOCKS = 4;

fake_head head;
malloc_header_chunk* malloc_head = 0;

typedef uint64_t* page_entry;
typedef page_entry* pt_t;
typedef pt_t* pdt_t;
typedef pdt_t* pdpt_t;
typedef pdpt_t* pml4t_t;

mmapentry* current_mmap_entry = nullptr;
uint64_t current_mmap_entry_position;

uint64_t pml4t_index = 0;
uint64_t pdpt_index = 0;
uint64_t pdt_index = 0;
uint64_t pt_index = 256;

uint64_t* allocate_block(uint64_t blocks){
    if(!current_mmap_entry){
        for(uint64_t i = 0; i < entry_count; ++i){
            auto& entry = e820_mmap[i];

            if(entry.type == 1 && entry.base >= 0x100000 && entry.size >= 16384){
                current_mmap_entry = &entry;
                current_mmap_entry_position = entry.base;
                break;
            }
        }
    }

    if(!current_mmap_entry){
        return nullptr;
    }

    pml4t_t pml4t = reinterpret_cast<pml4t_t>(0x70000);
    auto pdpt = reinterpret_cast<pdpt_t>(reinterpret_cast<uintptr_t>(pml4t[pml4t_index]) & ~0xFFF);
    auto pdt = reinterpret_cast<pdt_t>(reinterpret_cast<uintptr_t>(pdpt[pdpt_index]) & ~0xFFF);
    auto pt = reinterpret_cast<pt_t>(reinterpret_cast<uintptr_t>(pdt[pdt_index]) & ~0xFFF);

    if(pt_index + blocks >= 512){
        //TODO Go to a new page table
    }

    for(uint64_t i = 0; i < blocks; ++i){
        pt[pt_index + i] = reinterpret_cast<page_entry>((current_mmap_entry_position + i * BLOCK_SIZE) | 0x3);
    }

    auto block = reinterpret_cast<uint64_t*>(current_mmap_entry_position);

    pt_index += blocks;
    current_mmap_entry_position += blocks * BLOCK_SIZE;

    return block;
}

} //end of anonymous namespace

void init_memory_manager(){
    //Init the fake head
    head.size = 0;
    head.next = nullptr;
    head.prev = nullptr;
    head.size_2 = 0;

    malloc_head = reinterpret_cast<malloc_header_chunk*>(&head);

    auto block = allocate_block(MIN_BLOCKS);
    auto header = reinterpret_cast<malloc_header_chunk*>(block);

    header->size = MIN_BLOCKS * BLOCK_SIZE - META_SIZE;
    header->next = malloc_head;
    header->prev = malloc_head;

    auto footer = reinterpret_cast<malloc_footer_chunk*>(
        reinterpret_cast<uintptr_t>(block) + header->size + sizeof(malloc_header_chunk));
    footer->size = header->size;

    malloc_head->next = header;
    malloc_head->prev = header;
}

uint64_t* k_malloc(uint64_t bytes){
    auto current = malloc_head->next;

    while(true){
        if(current == malloc_head){
            //There are no blocks big enough to hold this request

            uint64_t* block = allocate_block(MIN_BLOCKS);
            auto header = reinterpret_cast<malloc_header_chunk*>(block);
            header->size = MIN_BLOCKS * BLOCK_SIZE - META_SIZE;

            current->next->prev = header;
            current->next = header;

            header->next  = current->next;
            header->prev = current;

            auto footer = reinterpret_cast<malloc_footer_chunk*>(
                reinterpret_cast<uintptr_t>(block) + header->size + sizeof(malloc_header_chunk));
            footer->size = header->size;
        } else if(current->size >= bytes){
            //This block is big enough

            //Is it worth splitting the block ?
            if(current->size - bytes - META_SIZE > MIN_SPLIT){
                auto new_block_size = current->size - bytes - META_SIZE;

                //Set the new size;
                current->size = bytes;

                auto footer = reinterpret_cast<malloc_footer_chunk*>(
                    reinterpret_cast<uintptr_t>(current) + bytes + sizeof(malloc_header_chunk));
                footer->size = bytes;

                auto new_block = reinterpret_cast<malloc_header_chunk*>(
                    reinterpret_cast<uintptr_t>(current) + bytes + META_SIZE);

                new_block->size = new_block_size;
                new_block->next = current->next;
                new_block->prev = current->prev;
                current->prev->next = new_block;
                current->next->prev = new_block;

                auto new_footer = reinterpret_cast<malloc_footer_chunk*>(
                    reinterpret_cast<uintptr_t>(new_block) + new_block_size + sizeof(malloc_header_chunk));
                new_footer->size = new_block_size;

                break;
            } else {
                //Remove this node from the free list
                current->prev->next = current->next;
                current->next->prev = current->prev;

                break;
            }
        }

        current = current->next;
    }

    _used_memory += bytes + META_SIZE;

    //Make sure the node is clean
    current->prev = nullptr;
    current->next = nullptr;

    return reinterpret_cast<uint64_t*>(
        reinterpret_cast<uintptr_t>(current) + sizeof(malloc_header_chunk));
}

void k_free(uint64_t* block){
    auto free_header = reinterpret_cast<malloc_header_chunk*>(
        reinterpret_cast<uintptr_t>(block) - sizeof(malloc_header_chunk));

    _used_memory -= free_header->size + META_SIZE;

    auto header = malloc_head;

    free_header->prev = header;
    free_header->next = header->next;

    header->next->prev = free_header;
    header->next = free_header;
}

void load_memory_map(){
    mmap_query(0, &e820_failed);
    mmap_query(1, &entry_count);
    mmap_query(2, reinterpret_cast<uint64_t*>(&e820_address));

    if(!e820_failed && e820_address){
        for(uint64_t i = 0; i < entry_count; ++i){
            auto& bios_entry = e820_address[i];
            auto& os_entry = e820_mmap[i];

            uint64_t base = bios_entry.base_low + (static_cast<uint64_t>(bios_entry.base_high) << 32);
            uint64_t length = bios_entry.length_low + (static_cast<uint64_t>(bios_entry.length_high) << 32);

            os_entry.base = base;
            os_entry.size = length;
            os_entry.type = bios_entry.type;

            if(os_entry.base == 0 && os_entry.type == 1){
                os_entry.type = 7;
            }

            if(os_entry.type == 1){
                _available_memory += os_entry.size;
            }
        }
    }
}

uint64_t mmap_entry_count(){
    return entry_count;
}

bool mmap_failed(){
    return e820_failed;
}

const mmapentry& mmap_entry(uint64_t i){
    return e820_mmap[i];
}

const char* str_e820_type(uint64_t type){
    switch(type){
        case 1:
            return "Free";
        case 2:
            return "Reserved";
        case 3:
        case 4:
            return "ACPI";
        case 5:
            return "Unusable";
        case 6:
            return "Disabled";
        case 7:
            return "Kernel";
        default:
            return "Unknown";
    }
}

uint64_t available_memory(){
    return _available_memory;
}

uint64_t used_memory(){
    return _used_memory;
}

uint64_t free_memory(){
    return _available_memory - _used_memory;
}
<|endoftext|>


<commit_before>#pragma once

#include <iostream>
#include <distributions/random_fwd.hpp>
#include <distributions/vector.hpp>

#ifdef __GNUG__
#  define LOOM_LIKELY(x) __builtin_expect(bool(x), true)
#  define LOOM_UNLIKELY(x) __builtin_expect(bool(x), false)
#else // __GNUG__
#  warning "ignoring LOOM_LIKELY(-), LOOM_UNLIKELY(-)"
#  define LOOM_LIKELY(x) (x)
#  define LOOM_UNLIKELY(x) (x)
#endif // __GNUG__

#ifndef LOOM_DEBUG_LEVEL
#  define LOOM_DEBUG_LEVEL 0
#endif // LOOM_DEBUG_LEVEL

#define LOOM_ERROR(message) {\
    std::cerr << "ERROR " << message << "\n\t"\
              << __FILE__ << " : " << __LINE__ << "\n\t"\
              << __PRETTY_FUNCTION__ << std::endl; \
    abort(); }

#define LOOM_ASSERT(cond, message) \
    { if (LOOM_UNLIKELY(not (cond))) LOOM_ERROR(message) }

#define LOOM_ASSERT_EQ(x, y) \
    LOOM_ASSERT((x) == (y), \
            "expected " #x " == " #y "; actual " << (x) << " vs " << (y))
#define LOOM_ASSERT_LE(x, y) \
    LOOM_ASSERT((x) <= (y), \
            "expected " #x " <= " #y "; actual " << (x) << " vs " << (y))
#define LOOM_ASSERT_LT(x, y) \
    LOOM_ASSERT((x) < (y), \
            "expected " #x " < " #y "; actual " << (x) << " vs " << (y))
#define LOOM_ASSERT_NE(x, y) \
    LOOM_ASSERT((x) != (y), \
            "expected " #x " != " #y "; actual " << (x) << " vs " << (y))

#define LOOM_ASSERT_(level, cond, message) \
    { if (LOOM_DEBUG_LEVEL >= (level)) LOOM_ASSERT(cond, message) }

#define LOOM_ASSERT1(cond, message) LOOM_ASSERT_(1, cond, message)
#define LOOM_ASSERT2(cond, message) LOOM_ASSERT_(2, cond, message)
#define LOOM_ASSERT3(cond, message) LOOM_ASSERT_(3, cond, message)

#define TODO(message) LOOM_ERROR("TODO " << message)

namespace loom
{

using distributions::rng_t;
using distributions::VectorFloat;

class noncopyable
{
    noncopyable (const noncopyable &) = delete;
    void operator= (const noncopyable &) = delete;
public:
    noncopyable () {}
};

template<class Value, typename... Args>
void inplace_destroy_and_construct (Value & value, Args... args)
{
    value->~Value();
    new (& value) Value(args...);
}

template<class T, class Alloc>
inline std::ostream & operator<< (
        std::ostream & os,
        const std::vector<T, Alloc> & vect)
{
    if (vect.empty()) {
        return os << "[]";
    } else {
        os << '[' << vect[0];
        for (size_t i = 1; i < vect.size(); ++i) {
            os << ", " << vect[i];
        }
        return os << ']';
    }
}

} // namespace loom
<commit_msg>Add LOOM_DEBUG macro<commit_after>#pragma once

#include <iostream>
#include <sstream>
#include <distributions/random_fwd.hpp>
#include <distributions/vector.hpp>

#ifdef __GNUG__
#  define LOOM_LIKELY(x) __builtin_expect(bool(x), true)
#  define LOOM_UNLIKELY(x) __builtin_expect(bool(x), false)
#else // __GNUG__
#  warning "ignoring LOOM_LIKELY(-), LOOM_UNLIKELY(-)"
#  define LOOM_LIKELY(x) (x)
#  define LOOM_UNLIKELY(x) (x)
#endif // __GNUG__

#ifndef LOOM_DEBUG_LEVEL
#  define LOOM_DEBUG_LEVEL 0
#endif // LOOM_DEBUG_LEVEL

#define LOOM_ERROR(message) {\
    std::cerr << "ERROR " << message << "\n\t"\
              << __FILE__ << " : " << __LINE__ << "\n\t"\
              << __PRETTY_FUNCTION__ << std::endl; \
    abort(); }

#define LOOM_DEBUG(message) {\
    std::ostringstream private_message; \
    private_message << "DEBUG " << message << '\n'; \
    std::cout << private_message.str() << std::flush; }

#define LOOM_ASSERT(cond, message) \
    { if (LOOM_UNLIKELY(not (cond))) LOOM_ERROR(message) }

#define LOOM_ASSERT_EQ(x, y) \
    LOOM_ASSERT((x) == (y), \
            "expected " #x " == " #y "; actual " << (x) << " vs " << (y))
#define LOOM_ASSERT_LE(x, y) \
    LOOM_ASSERT((x) <= (y), \
            "expected " #x " <= " #y "; actual " << (x) << " vs " << (y))
#define LOOM_ASSERT_LT(x, y) \
    LOOM_ASSERT((x) < (y), \
            "expected " #x " < " #y "; actual " << (x) << " vs " << (y))
#define LOOM_ASSERT_NE(x, y) \
    LOOM_ASSERT((x) != (y), \
            "expected " #x " != " #y "; actual " << (x) << " vs " << (y))

#define LOOM_ASSERT_(level, cond, message) \
    { if (LOOM_DEBUG_LEVEL >= (level)) LOOM_ASSERT(cond, message) }

#define LOOM_ASSERT1(cond, message) LOOM_ASSERT_(1, cond, message)
#define LOOM_ASSERT2(cond, message) LOOM_ASSERT_(2, cond, message)
#define LOOM_ASSERT3(cond, message) LOOM_ASSERT_(3, cond, message)

#define TODO(message) LOOM_ERROR("TODO " << message)

namespace loom
{

using distributions::rng_t;
using distributions::VectorFloat;

class noncopyable
{
    noncopyable (const noncopyable &) = delete;
    void operator= (const noncopyable &) = delete;
public:
    noncopyable () {}
};

template<class Value, typename... Args>
void inplace_destroy_and_construct (Value & value, Args... args)
{
    value->~Value();
    new (& value) Value(args...);
}

template<class T, class Alloc>
inline std::ostream & operator<< (
        std::ostream & os,
        const std::vector<T, Alloc> & vect)
{
    if (vect.empty()) {
        return os << "[]";
    } else {
        os << '[' << vect[0];
        for (size_t i = 1; i < vect.size(); ++i) {
            os << ", " << vect[i];
        }
        return os << ']';
    }
}

} // namespace loom
<|endoftext|>


<commit_before>// The MIT License (MIT)

// Copyright (c) 2013 lailongwei<lailongwei@126.com>
//
// 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.

#include "core/algo/TestCase_Core_Algo_RingBuffer.h"

TestCase_Core_Algo_RingBuffer::TestCase_Core_Algo_RingBuffer()
{
}

TestCase_Core_Algo_RingBuffer::~TestCase_Core_Algo_RingBuffer()
{
}

int TestCase_Core_Algo_RingBuffer::Run(int argc, char *argv[])
{
    std::cout << "core/algo/RingBuffer test:" << std::endl;

    DoBasicTest();
    DoPerfTest();

    std::cout << "Press any key to continue..." << std::endl;
    getchar();

    return 0;
}

void TestCase_Core_Algo_RingBuffer::DoBasicTest()
{
    std::cout << "RingBuffer Basic test:" << std::endl;
    {
        LLBC_RingBuffer<int> rb;
        std::cout << "- default ringbuffer capacity:" << rb.GetCapacity() << std::endl;
        std::cout << "- is empty: " << rb.IsEmpty() << ", is full: " << rb.IsFull() << std::endl;

        std::cout << "- push some elems..." << std::endl;
        for (int i = 0; i != rb.GetCapacity() / 2; ++i)
        {
            std::cout << "  - push: " << i << std::endl;
            rb.Push(i);
        }
        std::cout << "- after push, is empty: " << rb.IsEmpty() << ", is full: " << rb.IsFull() << std::endl;

        std::cout << "- pop some elems...";
        while (!rb.IsEmpty())
            std::cout << "  - pop: " << rb.Pop() << std::endl;
        std::cout << "- after pop, is empty: " << rb.IsEmpty() << ", is full: " << rb.IsFull() << std::endl;

        size_t oldCap = rb.GetCapacity();
        std::cout << "- auto recapacity test:" << std::endl;
        for (size_t i = 0; i < oldCap * 2; ++i)
        {
            std::cout << "  - push: " << i;
            rb.Push(i);
            std::cout << ", after push, capacity: " << rb.GetCapacity() << std::endl;
        }
        std::cout << "- after push elems, capacity:" << rb.GetCapacity() << ", is empty: " << rb.IsEmpty() << ", is full: " << rb.IsFull() << std::endl;
    }

    std::cout << "- random push/pop test: " << std::endl;
    {
        LLBC_RingBuffer<int> rb;
        LLBC_Random rand(static_cast<int>(LLBC_Time::NowTimeStamp()));
        for (int i = 0; i <100; ++i)
        {
            int pushTimes = rand.Rand(2, 1000);
            int popTimes = MAX(1, pushTimes - rand.Rand(1, 500));
            for (int j = 0; j < pushTimes; ++j)
                rb.Push(j);
            for (int j = 0; j < popTimes; ++j)
                rb.Pop();
        }

        std::cout << "- random push/pop test finished, please use dbg tools to check RingBuffer status" << std::endl;
    }
}

void TestCase_Core_Algo_RingBuffer::DoPerfTest()
{
    std::cout << "Performance test:" << std::endl;

#if LLBC_DEBUG
    const int testTimes = 10000;
#else
    const int testTimes = 1000000;
#endif

    LLBC_RingBuffer<int> rb(512);
    sint64 begTestTime = LLBC_GetMicroSeconds();
    for (int i = 0; i < testTimes; ++i)
    {
        for (int j = 0; j < 512; ++j)
            rb.Push(i);
        for (int j = 0; j < 512; ++j)
            rb.Pop();
    }
    sint64 usedTime = LLBC_GetMicroSeconds() - begTestTime;
    std::cout << "- test finished, used time(micro-seconds): " << usedTime << std::endl;
}

<commit_msg>Fix compile warnings on WINDOWS pf.<commit_after>// The MIT License (MIT)

// Copyright (c) 2013 lailongwei<lailongwei@126.com>
//
// 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.

#include "core/algo/TestCase_Core_Algo_RingBuffer.h"

TestCase_Core_Algo_RingBuffer::TestCase_Core_Algo_RingBuffer()
{
}

TestCase_Core_Algo_RingBuffer::~TestCase_Core_Algo_RingBuffer()
{
}

int TestCase_Core_Algo_RingBuffer::Run(int argc, char *argv[])
{
    std::cout << "core/algo/RingBuffer test:" << std::endl;

    DoBasicTest();
    DoPerfTest();

    std::cout << "Press any key to continue..." << std::endl;
    getchar();

    return 0;
}

void TestCase_Core_Algo_RingBuffer::DoBasicTest()
{
    std::cout << "RingBuffer Basic test:" << std::endl;
    {
        LLBC_RingBuffer<int> rb;
        std::cout << "- default ringbuffer capacity:" << rb.GetCapacity() << std::endl;
        std::cout << "- is empty: " << rb.IsEmpty() << ", is full: " << rb.IsFull() << std::endl;

        std::cout << "- push some elems..." << std::endl;
        for (int i = 0; i != rb.GetCapacity() / 2; ++i)
        {
            std::cout << "  - push: " << i << std::endl;
            rb.Push(i);
        }
        std::cout << "- after push, is empty: " << rb.IsEmpty() << ", is full: " << rb.IsFull() << std::endl;

        std::cout << "- pop some elems...";
        while (!rb.IsEmpty())
            std::cout << "  - pop: " << rb.Pop() << std::endl;
        std::cout << "- after pop, is empty: " << rb.IsEmpty() << ", is full: " << rb.IsFull() << std::endl;

        int oldCap = static_cast<int>(rb.GetCapacity());
        std::cout << "- auto recapacity test:" << std::endl;
        for (size_t i = 0; i < oldCap * 2; ++i)
        {
            std::cout << "  - push: " << i;
            rb.Push(i);
            std::cout << ", after push, capacity: " << rb.GetCapacity() << std::endl;
        }
        std::cout << "- after push elems, capacity:" << rb.GetCapacity() << ", is empty: " << rb.IsEmpty() << ", is full: " << rb.IsFull() << std::endl;
    }

    std::cout << "- random push/pop test: " << std::endl;
    {
        LLBC_RingBuffer<int> rb;
        LLBC_Random rand(static_cast<int>(LLBC_Time::NowTimeStamp()));
        for (int i = 0; i <100; ++i)
        {
            int pushTimes = rand.Rand(2, 1000);
            int popTimes = MAX(1, pushTimes - rand.Rand(1, 500));
            for (int j = 0; j < pushTimes; ++j)
                rb.Push(j);
            for (int j = 0; j < popTimes; ++j)
                rb.Pop();
        }

        std::cout << "- random push/pop test finished, please use dbg tools to check RingBuffer status" << std::endl;
    }
}

void TestCase_Core_Algo_RingBuffer::DoPerfTest()
{
    std::cout << "Performance test:" << std::endl;

#if LLBC_DEBUG
    const int testTimes = 10000;
#else
    const int testTimes = 1000000;
#endif

    LLBC_RingBuffer<int> rb(512);
    sint64 begTestTime = LLBC_GetMicroSeconds();
    for (int i = 0; i < testTimes; ++i)
    {
        for (int j = 0; j < 512; ++j)
            rb.Push(i);
        for (int j = 0; j < 512; ++j)
            rb.Pop();
    }
    sint64 usedTime = LLBC_GetMicroSeconds() - begTestTime;
    std::cout << "- test finished, used time(micro-seconds): " << usedTime << std::endl;
}

<|endoftext|>


<commit_before>#include "i2cif.h"
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <stdio.h>
#include <QCoreApplication>
#include <QSettings>
#include <QProcess>
#include <QThread>
#include <sailfishapp.h>
#include "conv.h"

I2cif::I2cif(QObject *parent) :
    QObject(parent)
{
    m_probingResult = QStringList();
    m_readResult = "Nothing yet";
    emit tohVddStatusChanged();
}

I2cif::~I2cif()
{
}

QStringList I2cif::i2cProbingStatus()
{
    return m_probingResult;
}

QString I2cif::i2cReadResult()
{
    return m_readResult;
}

/*
 * Function to set TOH VDD On and Off
 *
 *
 */

void I2cif::tohVddSet(QString onOff)
{
    int fd;

    fd = open("/sys/devices/platform/reg-userspace-consumer.0/state", O_WRONLY);

    if (!(fd < 0))
    {
        if (write (fd, QString::localeAwareCompare( onOff, "on") ? "0" : "1", 1) != 1)
            fprintf(stderr, "Vdd set failed\n");
        else
            fprintf(stderr, "Vdd set OK\n");

        close(fd);
    }
    else
        fprintf(stderr, "Vdd failed to open. Did you start i2ctool as root?\n");

    emit tohVddStatusChanged();
}

void I2cif::requestTohVddState()
{
    emit tohVddStatusChanged();
}

/*
 * Function to check which is current state of Vdd
 *
 */
bool I2cif::tohVddGet()
{
    int fd;
    int retval = 0;
    char buf[1] = { 0 };

    fd = open("/sys/devices/platform/reg-userspace-consumer.0/state", O_RDONLY);

    if (!(fd < 0))
    {
        retval += read(fd, buf ,1);
        close(fd);
    }

    return (buf[0] == 'e'); // values are "enabled" or "disabled"
}

/*
 * I2C Write Function
 *
 *
 */

void I2cif::i2cWrite(QString devName, unsigned char address, QString data)
{
    int file;
    char buf[200];
    bool parseOk;

    QByteArray tmpBa = devName.toUtf8();
    const char* devNameChar = tmpBa.constData();

    fprintf(stderr, "writing to address %02x: ", address);

    /* parse QString data to buf */
    QStringList bytes = data.split(" ");
    int i;
    for (i=0 ; i<bytes.length(); i++)
    {
        QString tmp = bytes.value(i);
        buf[i] = tmp.toInt(&parseOk, 16);
        if (!parseOk)
        {
            fprintf(stderr, "parsing error %d\n", i);
            emit i2cError();
            return;
        }
        fprintf(stderr, "%02x ", buf[i]);
    }
    fprintf(stderr, "\n");

    if ((file = open (devNameChar, O_RDWR)) < 0)
    {
        fprintf(stderr,"open error\n");
        emit i2cError();
        return;
    }

    if (ioctl(file, I2C_SLAVE, address) < 0)
    {
        close(file);
        fprintf(stderr,"ioctl error\n");
        emit i2cError();
        return;
    }

    /* write the data */
    if (write( file, buf, bytes.length() ) != bytes.length())
    {
        close(file);
        fprintf(stderr,"write error\n");
        emit i2cError();
        return;
    }

    close(file);

    fprintf(stderr,"write ok\n");

    emit i2cWriteOk();

}

/*
 * I2C Read function
 *
 */

void I2cif::i2cRead(QString devName, unsigned char address, int count)
{
    int file;
    char buf[200];
    Conv conv;

    m_readResult = "";
    //emit i2cReadResultChanged();

    QByteArray tmpBa = devName.toUtf8();
    const char* devNameChar = tmpBa.constData();

    fprintf(stderr, "reading from address %02x count %d\n", address, count);

    if ((file = open (devNameChar, O_RDWR)) < 0)
    {
        fprintf(stderr,"open error\n");
        emit i2cError();
        return;
    }

    if (ioctl(file, I2C_SLAVE, address) < 0)
    {
        close(file);
        fprintf(stderr,"ioctl error\n");
        emit i2cError();
        return;
    }

    /* Read data */
    if (read( file, buf, count ) != count)
    {
        close(file);
        fprintf(stderr,"read error\n");
        emit i2cError();
        return;
    }

    close(file);

    /* copy buf to m_readResult */
    int i;

    fprintf(stderr, "read ");
    for (i=0; i<count ; i++)
    {
        m_readResult = m_readResult + conv.toHex(buf[i],2) + " ";
        fprintf(stderr, "%02x ", buf[i]);
    }
    fprintf(stderr, "\n");

    emit i2cReadResultChanged();
}
/*
 * I2C write then read with repeated stop
 */

void I2cif::i2cWriteThenRead(QString devName, unsigned char address, QString data, int count)
{
    int file;
    Conv conv;
    m_readResult = QString();

    QByteArray tmpBa = devName.toUtf8();
    const char* devNameChar = tmpBa.constData();

    if ((file = open (devNameChar, O_RDWR)) < 0)
    {
        fprintf(stderr,"open error\n");
        emit i2cError();
        return;
    }

    struct i2c_rdwr_ioctl_data i2c_data;
    struct i2c_msg msg[2];
    unsigned char *buftx;
    unsigned char *bufrx;

    bufrx = (unsigned char *)malloc(count +1);

    i2c_data.msgs = msg;
    i2c_data.nmsgs = 2;

    QStringList bytes = data.split(" ");
    int i;
    buftx = (unsigned char *)malloc(bytes.length()+1);
    for (i=0 ; i<bytes.length(); i++)
    {
        bool parseOk;
        QString tmp = bytes.value(i);
        buftx[i] = tmp.toInt(&parseOk, 16);
        if (!parseOk)
        {
            fprintf(stderr, "parsing error %d\n", i);
            emit i2cError();
            return;
        }
        fprintf(stderr, "%02x ", buftx[i]);
    }
    fprintf(stderr, "\n");

    i2c_data.msgs[0].addr = address;
    i2c_data.msgs[0].flags = 0;
    i2c_data.msgs[0].len = bytes.length();
    i2c_data.msgs[0].buf = (unsigned char *)buftx;

    i2c_data.msgs[1].addr = address;
    i2c_data.msgs[1].flags = I2C_M_RD;
    i2c_data.msgs[1].len = count;
    i2c_data.msgs[1].buf = (unsigned char *)bufrx;

    int ret = ioctl(file, I2C_RDWR, &i2c_data);

    if (ret < 0)
    {
            fprintf(stderr, "read data fail %d\n", ret);
            emit i2cError();
            return;
    }

    close(file);

    fprintf(stderr, "read ");
    for (i=0; i<count ; i++)
    {
        m_readResult = m_readResult + conv.toHex(bufrx[i],2) + " ";
        fprintf(stderr, "%02x ", bufrx[i]);
    }
    fprintf(stderr, "\n");

    emit i2cReadResultChanged();

}

/*
 * Simple probing function to check its presence in I2C bus
 *
 * Returns a stringlist through i2cProbingStatus()
 * emits a i2cProbingChanged() signal when complete
 *
 * "ok" - reading 2 bytes was succesful
 * "openFail - open() command faild to open device
 * "ioctlFail" - ioctl() to slave address failed
 * "readFail" - read() 2 bytes from slave failed (basically NACK)
 * "skipped" - addresses 4...7 are skipped to speed up operation
 *
 */

void I2cif::i2cProbe(QString devName)
{
    int file;
    char buf[2];
    unsigned char address;

    m_probingResult.clear();

    for (address = 0; address < 128; address++)
    {

        /* These few addresses takes long time to probe, so skip them brutely */
        if (address >= 4 && address <= 7)
        {
            m_probingResult.append("skipped");
            continue;
        }

        QByteArray tmpBa = devName.toUtf8();
        const char* devNameChar = tmpBa.constData();

        fprintf(stderr, "probing %s address %02x: ", devNameChar, address);

        if ((file = open (devNameChar, O_RDWR)) < 0)
        {
            m_probingResult.append("openFail");
            fprintf(stderr, "open failed\n");
            close(file);
            continue;
        }

        if (ioctl(file, I2C_SLAVE, address) < 0)
        {
            close(file);
            m_probingResult.append("ioctlFail");
            fprintf(stderr, "ioctl failed\n");
            close(file);
            continue;
        }

        /* Try to read 2 bytes. This is also safe for LM75 */
        if (read( file, buf, 2 ) != 2)
        {
            close(file);
            m_probingResult.append("readFail");
            fprintf(stderr, "read failed\n");
            close(file);
            continue;
        }

        close(file);
        m_probingResult.append("ok");
        fprintf(stderr, "device found at address %02x\n", address);
    }

    emit i2cProbingChanged();

}

/*
 *  If microswitch is pressed tohd takes control over i2c-1-0050 (eeprom)
 *  this is used to release it.
 *  but duh, needs to be done as root
 *  echo toh-core.0 > /sys/bus/platform/drivers/toh-core/unbind
*/

void I2cif::unbindTohCore()
{
    int fd;

    fd = open("/sys/bus/platform/drivers/toh-core/unbind", O_WRONLY);

    if (!(fd < 0))
    {
        if (write (fd, "toh-core.0", 10) != 10)
            fprintf(stderr, "unbind failed\n");
        else
            fprintf(stderr, "unbind OK\n");

        close(fd);
    }
    else
        fprintf(stderr, "unbind failed. Did you start i2ctool as root?\n");
}

/*
 * Default values commands
 *
 */

void I2cif::setAsDefault(QString index, QString value)
{
    QSettings s("harbour-i2ctool", "harbour-i2ctool");
    s.beginGroup("Defaults");
    s.setValue(index, value);
    s.endGroup();
}

QString I2cif::getDefault(QString index)
{
    QString value;

    QSettings s("harbour-i2ctool", "harbour-i2ctool");
    s.beginGroup("Defaults");
    value = s.value(index, firstTimeDefault(index)).toString();
    s.endGroup();

    return value;
}

/* helper :) */
QString I2cif::firstTimeDefault(QString index)
{
    if (index == "0") return "4B4C";
    if (index == "1") return "0001";
    if (index == "2") return "01";
    if (index == "3") return "0100";
    if (index == "4") return "0040";
    if (index == "5") return "0040";
    if (index == "6") return "0080";
    if (index == "7") return "0000";
    return "0000";
}

/* use xdg-open to start pdf-viewer for showing usersguide
*/
void I2cif::openUsersGuide()
{
    QProcess proc;
    QString ugpath = SailfishApp::pathTo("i2ctool-ug.pdf").toString();

    fprintf(stderr, "loading user's guide %s\n", qPrintable(ugpath));

    proc.startDetached("/usr/bin/xdg-open" , QStringList() << ugpath);

    QThread::msleep(100);
}
<commit_msg>fixed bug #4<commit_after>#include "i2cif.h"
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <stdio.h>
#include <QCoreApplication>
#include <QSettings>
#include <QProcess>
#include <QThread>
#include <sailfishapp.h>
#include "conv.h"
#include <unistd.h>

I2cif::I2cif(QObject *parent) :
    QObject(parent)
{
    m_probingResult = QStringList();
    m_readResult = "Nothing yet";
    emit tohVddStatusChanged();
}

I2cif::~I2cif()
{
}

QStringList I2cif::i2cProbingStatus()
{
    return m_probingResult;
}

QString I2cif::i2cReadResult()
{
    return m_readResult;
}

/*
 * Function to set TOH VDD On and Off
 *
 *
 */

void I2cif::tohVddSet(QString onOff)
{
    int fd;

    fd = open("/sys/devices/platform/reg-userspace-consumer.0/state", O_WRONLY);

    if (!(fd < 0))
    {
        if (write (fd, QString::localeAwareCompare( onOff, "on") ? "0" : "1", 1) != 1)
            fprintf(stderr, "Vdd set failed\n");
        else
            fprintf(stderr, "Vdd set OK\n");

        close(fd);
    }
    else
        fprintf(stderr, "Vdd failed to open. Did you start i2ctool as root?\n");

    emit tohVddStatusChanged();
}

void I2cif::requestTohVddState()
{
    emit tohVddStatusChanged();
}

/*
 * Function to check which is current state of Vdd
 *
 */
bool I2cif::tohVddGet()
{
    int fd;
    int retval = 0;
    char buf[1] = { 0 };

    fd = open("/sys/devices/platform/reg-userspace-consumer.0/state", O_RDONLY);

    if (!(fd < 0))
    {
        retval += read(fd, buf ,1);
        close(fd);
    }

    return (buf[0] == 'e'); // values are "enabled" or "disabled"
}

/*
 * I2C Write Function
 *
 *
 */

void I2cif::i2cWrite(QString devName, unsigned char address, QString data)
{
    int file;
    char buf[200];
    bool parseOk;

    QByteArray tmpBa = devName.toUtf8();
    const char* devNameChar = tmpBa.constData();

    fprintf(stderr, "writing to address %02x: ", address);

    /* parse QString data to buf */
    QStringList bytes = data.split(" ");
    int i;
    for (i=0 ; i<bytes.length(); i++)
    {
        QString tmp = bytes.value(i);
        buf[i] = tmp.toInt(&parseOk, 16);
        if (!parseOk)
        {
            fprintf(stderr, "parsing error %d\n", i);
            emit i2cError();
            return;
        }
        fprintf(stderr, "%02x ", buf[i]);
    }
    fprintf(stderr, "\n");

    if ((file = open (devNameChar, O_RDWR)) < 0)
    {
        fprintf(stderr,"open error\n");
        emit i2cError();
        return;
    }

    if (ioctl(file, I2C_SLAVE, address) < 0)
    {
        close(file);
        fprintf(stderr,"ioctl error\n");
        emit i2cError();
        return;
    }

    /* write the data */
    if (write( file, buf, bytes.length() ) != bytes.length())
    {
        close(file);
        fprintf(stderr,"write error\n");
        emit i2cError();
        return;
    }

    close(file);

    fprintf(stderr,"write ok\n");

    emit i2cWriteOk();

}

/*
 * I2C Read function
 *
 */

void I2cif::i2cRead(QString devName, unsigned char address, int count)
{
    int file;
    char buf[200];
    Conv conv;

    m_readResult = "";
    //emit i2cReadResultChanged();

    QByteArray tmpBa = devName.toUtf8();
    const char* devNameChar = tmpBa.constData();

    fprintf(stderr, "reading from address %02x count %d\n", address, count);

    if ((file = open (devNameChar, O_RDWR)) < 0)
    {
        fprintf(stderr,"open error\n");
        emit i2cError();
        return;
    }

    if (ioctl(file, I2C_SLAVE, address) < 0)
    {
        close(file);
        fprintf(stderr,"ioctl error\n");
        emit i2cError();
        return;
    }

    /* Read data */
    if (read( file, buf, count ) != count)
    {
        close(file);
        fprintf(stderr,"read error\n");
        emit i2cError();
        return;
    }

    close(file);

    /* copy buf to m_readResult */
    int i;

    fprintf(stderr, "read ");
    for (i=0; i<count ; i++)
    {
        m_readResult = m_readResult + conv.toHex(buf[i],2) + " ";
        fprintf(stderr, "%02x ", buf[i]);
    }
    fprintf(stderr, "\n");

    emit i2cReadResultChanged();
}
/*
 * I2C write then read with repeated stop
 */

void I2cif::i2cWriteThenRead(QString devName, unsigned char address, QString data, int count)
{
    int file;
    Conv conv;
    m_readResult = QString();

    QByteArray tmpBa = devName.toUtf8();
    const char* devNameChar = tmpBa.constData();

    if ((file = open (devNameChar, O_RDWR)) < 0)
    {
        fprintf(stderr,"open error\n");
        emit i2cError();
        return;
    }

    struct i2c_rdwr_ioctl_data i2c_data;
    struct i2c_msg msg[2];
    unsigned char *buftx;
    unsigned char *bufrx;

    bufrx = (unsigned char *)malloc(count +1);

    i2c_data.msgs = msg;
    i2c_data.nmsgs = 2;

    QStringList bytes = data.split(" ");
    int i;
    buftx = (unsigned char *)malloc(bytes.length()+1);
    for (i=0 ; i<bytes.length(); i++)
    {
        bool parseOk;
        QString tmp = bytes.value(i);
        buftx[i] = tmp.toInt(&parseOk, 16);
        if (!parseOk)
        {
            fprintf(stderr, "parsing error %d\n", i);
            emit i2cError();
            return;
        }
        fprintf(stderr, "%02x ", buftx[i]);
    }
    fprintf(stderr, "\n");

    i2c_data.msgs[0].addr = address;
    i2c_data.msgs[0].flags = 0;
    i2c_data.msgs[0].len = bytes.length();
    i2c_data.msgs[0].buf = (unsigned char *)buftx;

    i2c_data.msgs[1].addr = address;
    i2c_data.msgs[1].flags = I2C_M_RD;
    i2c_data.msgs[1].len = count;
    i2c_data.msgs[1].buf = (unsigned char *)bufrx;

    int ret = ioctl(file, I2C_RDWR, &i2c_data);

    if (ret < 0)
    {
            fprintf(stderr, "read data fail %d\n", ret);
            emit i2cError();
            return;
    }

    close(file);

    fprintf(stderr, "read ");
    for (i=0; i<count ; i++)
    {
        m_readResult = m_readResult + conv.toHex(bufrx[i],2) + " ";
        fprintf(stderr, "%02x ", bufrx[i]);
    }
    fprintf(stderr, "\n");

    emit i2cReadResultChanged();

}

/*
 * Simple probing function to check its presence in I2C bus
 *
 * Returns a stringlist through i2cProbingStatus()
 * emits a i2cProbingChanged() signal when complete
 *
 * "ok" - reading 2 bytes was succesful
 * "openFail - open() command faild to open device
 * "ioctlFail" - ioctl() to slave address failed
 * "readFail" - read() 2 bytes from slave failed (basically NACK)
 * "skipped" - addresses 4...7 are skipped to speed up operation
 *
 */

void I2cif::i2cProbe(QString devName)
{
    int file;
    char buf[2];
    unsigned char address;

    m_probingResult.clear();

    for (address = 0; address < 128; address++)
    {

        /* These few addresses takes long time to probe, so skip them brutely */
        if (address >= 4 && address <= 7)
        {
            m_probingResult.append("skipped");
            continue;
        }

        QByteArray tmpBa = devName.toUtf8();
        const char* devNameChar = tmpBa.constData();

        fprintf(stderr, "probing %s address %02x: ", devNameChar, address);

        if ((file = open (devNameChar, O_RDWR)) < 0)
        {
            m_probingResult.append("openFail");
            fprintf(stderr, "open failed\n");
            close(file);
            continue;
        }

        if (ioctl(file, I2C_SLAVE, address) < 0)
        {
            close(file);
            m_probingResult.append("ioctlFail");
            fprintf(stderr, "ioctl failed\n");
            close(file);
            continue;
        }

        /* Try to read 2 bytes. This is also safe for LM75 */
        if (read( file, buf, 2 ) != 2)
        {
            close(file);
            m_probingResult.append("readFail");
            fprintf(stderr, "read failed\n");
            close(file);
            continue;
        }

        close(file);
        m_probingResult.append("ok");
        fprintf(stderr, "device found at address %02x\n", address);
    }

    emit i2cProbingChanged();

}

/*
 *  If microswitch is pressed tohd takes control over i2c-1-0050 (eeprom)
 *  this is used to release it.
 *  but duh, needs to be done as root
 *  echo toh-core.0 > /sys/bus/platform/drivers/toh-core/unbind
*/

void I2cif::unbindTohCore()
{
    int fd;

    fd = open("/sys/bus/platform/drivers/toh-core/unbind", O_WRONLY);

    if (!(fd < 0))
    {
        if (write (fd, "toh-core.0", 10) != 10)
            fprintf(stderr, "unbind failed\n");
        else
            fprintf(stderr, "unbind OK\n");

        close(fd);
    }
    else
        fprintf(stderr, "unbind failed. Did you start i2ctool as root?\n");
}

/*
 * Default values commands
 *
 */

void I2cif::setAsDefault(QString index, QString value)
{
    QSettings s("harbour-i2ctool", "harbour-i2ctool");
    s.beginGroup("Defaults");
    s.setValue(index, value);
    s.endGroup();
}

QString I2cif::getDefault(QString index)
{
    QString value;

    QSettings s("harbour-i2ctool", "harbour-i2ctool");
    s.beginGroup("Defaults");
    value = s.value(index, firstTimeDefault(index)).toString();
    s.endGroup();

    return value;
}

/* helper :) */
QString I2cif::firstTimeDefault(QString index)
{
    if (index == "0") return "4B4C";
    if (index == "1") return "0001";
    if (index == "2") return "01";
    if (index == "3") return "0100";
    if (index == "4") return "0040";
    if (index == "5") return "0040";
    if (index == "6") return "0080";
    if (index == "7") return "0000";
    return "0000";
}

/* use xdg-open to start pdf-viewer for showing usersguide
*/
void I2cif::openUsersGuide()
{
    QProcess proc;
    QString ugpath = SailfishApp::pathTo("i2ctool-ug.pdf").toString();

    fprintf(stderr, "loading user's guide %s\n", qPrintable(ugpath));

    proc.startDetached("/usr/bin/xdg-open" , QStringList() << ugpath);

    QThread::msleep(100);
}
<|endoftext|>


<commit_before>// Copyright (C) 2009, 2010 by Thomas Moulard, CNRS.
//
// This file is part of the hppWalkFootPlanner.
//
// hppWalkFootPlanner is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// hppWalkFootPlanner is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with hppWalkFootPlanner.  If not, see <http://www.gnu.org/licenses/>.

#include <cassert>
#include <iomanip>
#include <ostream>

#include "hpp/util/indent.hh"

namespace hpp
{
  inline long& indent (std::ostream& o)
  {
    // The slot to store the current indentation level.
    static const int indent_index = std::ios::xalloc ();
    return o.iword (indent_index);
  }

  std::ostream& incindent (std::ostream& o)
  {
    indent (o) += 2;
    return o;
  }

  std::ostream& decindent (std::ostream& o)
  {
    assert (indent (o));
    indent (o) -= 2;
    return o;
  }

  std::ostream& resetindent (std::ostream& o)
  {
    indent (o) = 0;
    return o;
  }

  std::ostream& iendl (std::ostream& o)
  {
    o << std::endl;
    // Be sure to be able to restore the stream flags.
    char fill = o.fill (' ');
    return o << std::setw (indent (o))
	     << ""
	     << std::setfill (fill);
  }

  std::ostream& incendl (std::ostream& o)
  {
    return o << incindent << iendl;
  }

  std::ostream& decendl (std::ostream& o)
  {
    return o << decindent << iendl;
  }

} // end of namespace hpp.
<commit_msg>Fix compilation on x86_64.<commit_after>// Copyright (C) 2009, 2010 by Thomas Moulard, CNRS.
//
// This file is part of the hppWalkFootPlanner.
//
// hppWalkFootPlanner is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// hppWalkFootPlanner is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with hppWalkFootPlanner.  If not, see <http://www.gnu.org/licenses/>.

#include <cassert>
#include <iomanip>
#include <ostream>

#include "hpp/util/indent.hh"

namespace hpp
{
  inline long& indent (std::ostream& o)
  {
    // The slot to store the current indentation level.
    static const int indent_index = std::ios::xalloc ();
    return o.iword (indent_index);
  }

  std::ostream& incindent (std::ostream& o)
  {
    indent (o) += 2;
    return o;
  }

  std::ostream& decindent (std::ostream& o)
  {
    assert (indent (o));
    indent (o) -= 2;
    return o;
  }

  std::ostream& resetindent (std::ostream& o)
  {
    indent (o) = 0;
    return o;
  }

  std::ostream& iendl (std::ostream& o)
  {
    o << std::endl;
    // Be sure to be able to restore the stream flags.
    char fill = o.fill (' ');
    return o << std::setw ((int)indent (o))
	     << ""
	     << std::setfill (fill);
  }

  std::ostream& incendl (std::ostream& o)
  {
    return o << incindent << iendl;
  }

  std::ostream& decendl (std::ostream& o)
  {
    return o << decindent << iendl;
  }

} // end of namespace hpp.
<|endoftext|>