<commit_before>#ifndef _list_hpp_1337420
#define _list_hpp_1337420

#include <iterator>
#include <type_traits>

#include "../ztl_base.hpp"

__ztl_namespace_start
	template<typename Key>
	struct list_node
	{
		list_node* m_next;
		list_node* m_prev;
		Key m_data;

		void hook(list_node* const _position) {
			this->m_prev = _position->m_prev;
			this->m_next = _position;
			this->m_prev->m_next = this;
			_position->m_prev = this;
		}

		void unhook() {
			this->m_prev->m_next = this->m_next;
			this->m_next->m_prev = this->m_prev;
		}
	};

	template<typename Key>
	struct list_iterator
	{
		typedef list_iterator<Key>								Self;
		typedef list_node<Key>									Node;
		typedef ptrdiff_t										difference_type;
		typedef __stl::bidirectional_iterator_tag				iterator_category;
		typedef Key												value_type;
		typedef Key*											pointer;
		typedef Key&											reference;

		list_iterator() { }
		list_iterator(Node* _x) : ptr(_x) { }

		inline reference	operator*() const { return ptr->m_data; }
		inline pointer		operator->() const { return &ptr->m_data; }
		inline Self&		operator++() { ptr = ptr->m_next; return *this; }
		inline Self			operator++(int) { Self tmp = *this; ptr = ptr->m_next; return tmp; }
		inline Self&		operator--() { ptr = ptr->m_prev; return *this; }
		inline Self			operator--(int) { Self tmp = *this; ptr = ptr->m_prev; return tmp; }
		inline bool			operator==(const Self& _x) const { return ptr == _x.ptr; }
		inline bool			operator!=(const Self& _x) const { return ptr != _x.ptr; }

		inline Self&		operator+(int _x) { for (; _x > 0; --_x) ptr = ptr->m_next; return *this; }
		inline Self&		operator-(int _x) { for (; _x > 0; --_x) ptr = ptr->m_prev; return *this; }

		Node* ptr;
	};

	template<typename Key>
	struct list_const_iterator
	{
		typedef list_const_iterator<Key>						Self;
		typedef const list_node<Key>							Node;
		typedef list_iterator<Key>								iterator;
		typedef ptrdiff_t										difference_type;
		typedef __stl::bidirectional_iterator_tag					iterator_category;
		typedef const Key										value_type;
		typedef const Key*										pointer;
		typedef const Key&										reference;

		list_const_iterator() { }
		list_const_iterator(const Node* _x) : ptr(_x) { }
		list_const_iterator(const iterator& _x) : ptr(_x.ptr) { }

		inline reference	operator*() const { return ptr->m_data; }
		inline pointer		operator->() const { return &ptr->m_data; }
		inline Self&		operator++() { ptr = ptr->m_next; return *this; }
		inline Self			operator++(int) { Self tmp = *this; ptr = ptr->m_next; return tmp; }
		inline Self&		operator--() { ptr = ptr->m_prev; return *this; }
		inline Self			operator--(int) { Self tmp = *this; ptr = ptr->m_prev;	return tmp; }
		inline bool			operator==(const Self& _x) const { return ptr == _x.ptr; }
		inline bool			operator!=(const Self& _x) const { return ptr != _x.ptr; }

		inline Self&		operator+(int _x) { for (; _x > 0; --_x) ptr = ptr->m_next; return *this; }
		inline Self&		operator-(int _x) { for (; _x > 0; --_x) ptr = ptr->m_prev; return *this; }

		const Node* ptr;
	};

	template<typename Key>
	class list
	{
	public:
		typedef Key												value_type;
		typedef Key*											pointer;
		typedef const Key*										const_pointer;
		typedef Key&											reference;
		typedef const Key&										const_reference;

		typedef list_iterator<Key>								iterator;
		typedef list_const_iterator<Key>						const_iterator;
		typedef __stl::reverse_iterator<const_iterator>			const_reverse_iterator;
		typedef __stl::reverse_iterator<iterator>				reverse_iterator;
		typedef size_t											size_type;
		typedef ptrdiff_t										difference_type;

	protected:
		typedef list_node<Key>									Node;
		Node init;

		inline Node* m_create_node(const Key& _x) {
			Node* tmp = (Node*)malloc(sizeof(Node));
			tmp->m_data = _x;
			return tmp;
		}

		inline Node*		m_create_node() { return (Node*)malloc(sizeof(Node)); }
		inline void			m_clear() { this->erase(begin(), end()); }
		inline void			m_init() { this->init.m_next = this->init.m_prev = &this->init; }

		inline void			m_fill_insert(iterator _pos, size_type _n, const Key& _x) {
			for (; _n > 0; --_n) this->m_insert(_pos, _x);
		}

		inline void			m_insert(iterator _position, const value_type& _x) {
			this->m_create_node(_x)->hook(_position.ptr);
		}

		inline void			m_erase(iterator _position) {
			_position.ptr->unhook();
			free(_position.ptr);
		}

		template<typename __Int>
		inline void			m_insert_dispatch(iterator _pos, __Int _n, __Int _x, __stl::true_type) {
			this->m_fill_insert(_pos, static_cast<size_type>(_n), static_cast<Key>(_x));
		}

		template<typename Iter>
		inline void			m_insert_dispatch(iterator _pos, Iter _first, Iter _last, __stl::false_type) {
			for (; _first != _last; ++_first) this->m_insert(_pos, *_first);
		}

		inline void			m_transfer(iterator _position, iterator _first, iterator _last) {
			if (_position != _last) {
				_last.ptr->m_prev->m_next = _position.ptr;
				_first.ptr->m_prev->m_next = _last.ptr;
				_position.ptr->m_prev->m_next = _first.ptr;

				Node* tmp = _position.ptr->m_prev;
				_position.ptr->m_prev = _last.ptr->m_prev;
				_last.ptr->m_prev = _first.ptr->m_prev;
				_first.ptr->m_prev = tmp;
			}
		}

	public:
		explicit list() : init(*m_create_node()) { m_init(); }
		explicit list(size_type _n) : init(*m_create_node()) { m_init(); this->insert(begin(), _n, Key()); }
		list(size_type _n, const Key& _value) : init(*m_create_node()) { m_init(); this->insert(begin(), _n, _value); }
		list(const list& _x) : init(*m_create_node()) { m_init(); this->insert(begin(), _x.begin(), _x.end()); }

		template<typename Iter>
		list(Iter _first, Iter _last) : init(*m_create_node()) { m_init(); this->insert(begin(), _first, _last); }

		~list() {
			/*Node* node, *tmp = &this->init;
			while (tmp) {
			node = tmp->m_next;
			delete node;
			}*/
		}

		/* Iterator operations */
		inline iterator							begin() { return (iterator)this->init.m_next; }
		inline const_iterator					cbegin() const { return (iterator)this->init.m_next; }
		inline iterator							end() { return (iterator)&this->init; }
		inline const_iterator					cend() const { return (iterator)&this->init; }

		inline reverse_iterator					rbegin() { return reverse_iterator(end()); }
		inline const_reverse_iterator			crbegin() const { return const_reverse_iterator(cend()); }
		inline reverse_iterator					rend() { return reverse_iterator(begin()); }
		inline const_reverse_iterator			crend() const { return const_reverse_iterator(cbegin()); }

		/* Size Operations */
		inline bool								empty() const { return this->init.m_next == &this->init; }
		inline size_type						size() const { return __stl::distance(begin(), end()); }
		inline size_type						max_size() const { return size_type(-1); }

		/* Element access */
		inline reference						front() { return *begin(); }
		inline const_reference					front() const { return *begin(); }
		inline reference						back() { return *(--end()); }
		inline const_reference					back() const { return *(--end()); }

		/* Modifiers */
		inline void								push_front(const Key& _x) { this->m_insert(begin(), _x); }
		inline void								pop_front() { this->m_erase(begin()); }
		inline void								push_back(const Key& _x) { this->m_insert(end(), _x); }
		inline void								pop_back() { this->m_erase(this->init.m_prev); }

		inline iterator		insert(iterator _pos, const Key& _x) { this->m_insert(_pos, _x); return --_pos; }
		inline void			insert(iterator _pos, size_type _n, const Key& _x) { this->m_fill_insert(_pos, _n, _x); }

		template<typename Iter>
		inline void			insert(iterator _pos, Iter _first, Iter _last) { this->m_insert_dispatch(_position, _first, _last, __stl::is_integral<Iter>::value); }

		inline iterator		erase(iterator _pos) { this->m_erase(_pos++); return _pos; }
		inline iterator		erase(iterator _first, iterator _last) { while (_first != _last) _first = erase(_first); return _last; }
		inline void			clear() { this->m_clear(); this->m_init(); }

		inline void			remove(const Key& _value) {
			for (iterator it = begin(); it != end(); ++it) {
				if (it.ptr->m_data == _value)
					it = this->erase(it);
			}
		}

		template <class Predicate>
		inline void			remove_if(Predicate _pred) {
			for (iterator it = begin(); it != end(); ++it) {
				if (_pred(*it))
					it = this->erase(it);

				// Fix last item delete
				if (_pred(back())) pop_back();
			}
		}

		/* Operators */
		inline bool operator==(const list& _x) {
			const_iterator end1 = end();
			const_iterator end2 = _x.end();

			const_iterator it1 = begin();
			const_iterator it2 = _x.begin();
			while (it1 != end1 && it2 != end2 && *it1 == *it2) {
				++it1;
				++it2;
			}

			return it1 == end1 && it2 == end2;
		}

		inline bool operator<(const list& _x) { return __stl::lexicographical_compare(_x.begin(), _x.end(), begin(), end()); }
		inline bool operator>(const list& _x) { return _x < *this; }
		inline bool operator!=(const list<Key>& _x) { return !(_x == *this); }
		inline bool	operator<=(const list<Key>& _x) { return !(_x < *this); }
		inline bool operator>=(const list<Key>& _x) { return !(*this < _x); }
	};
__ztl_namespace_end

#endif /* _list_hpp_1337420 */
<commit_msg>Update list.hpp<commit_after>#ifndef _list_hpp_1337420
#define _list_hpp_1337420

#include <iterator>
#include <type_traits>

#include "../ztl_base.hpp"

__ztl_namespace_start
	template<typename Key>
	struct list_node
	{
		list_node* m_next;
		list_node* m_prev;
		Key m_data;

		void hook(list_node* const _position) {
			this->m_prev = _position->m_prev;
			this->m_next = _position;
			this->m_prev->m_next = this;
			_position->m_prev = this;
		}

		void unhook() {
			this->m_prev->m_next = this->m_next;
			this->m_next->m_prev = this->m_prev;
		}
	};

	template<typename Key>
	struct list_iterator
	{
		typedef list_iterator<Key>			Self;
		typedef list_node<Key>				Node;
		typedef ptrdiff_t				difference_type;
		typedef __stl::bidirectional_iterator_tag	iterator_category;
		typedef Key					value_type;
		typedef Key*					pointer;
		typedef Key&					reference;

		list_iterator() { }
		list_iterator(Node* _x) : ptr(_x) { }

		inline reference	operator*() const { return ptr->m_data; }
		inline pointer		operator->() const { return &ptr->m_data; }
		inline Self&		operator++() { ptr = ptr->m_next; return *this; }
		inline Self		operator++(int) { Self tmp = *this; ptr = ptr->m_next; return tmp; }
		inline Self&		operator--() { ptr = ptr->m_prev; return *this; }
		inline Self		operator--(int) { Self tmp = *this; ptr = ptr->m_prev; return tmp; }
		inline bool		operator==(const Self& _x) const { return ptr == _x.ptr; }
		inline bool		operator!=(const Self& _x) const { return ptr != _x.ptr; }

		inline Self&		operator+(int _x) { for (; _x > 0; --_x) ptr = ptr->m_next; return *this; }
		inline Self&		operator-(int _x) { for (; _x > 0; --_x) ptr = ptr->m_prev; return *this; }

		Node* ptr;
	};

	template<typename Key>
	struct list_const_iterator
	{
		typedef list_const_iterator<Key>						Self;
		typedef const list_node<Key>							Node;
		typedef list_iterator<Key>							iterator;
		typedef ptrdiff_t								difference_type;
		typedef __stl::bidirectional_iterator_tag					iterator_category;
		typedef const Key								value_type;
		typedef const Key*								pointer;
		typedef const Key&								reference;

		list_const_iterator() { }
		list_const_iterator(const Node* _x) : ptr(_x) { }
		list_const_iterator(const iterator& _x) : ptr(_x.ptr) { }

		inline reference	operator*() const { return ptr->m_data; }
		inline pointer		operator->() const { return &ptr->m_data; }
		inline Self&		operator++() { ptr = ptr->m_next; return *this; }
		inline Self		operator++(int) { Self tmp = *this; ptr = ptr->m_next; return tmp; }
		inline Self&		operator--() { ptr = ptr->m_prev; return *this; }
		inline Self		operator--(int) { Self tmp = *this; ptr = ptr->m_prev;	return tmp; }
		inline bool		operator==(const Self& _x) const { return ptr == _x.ptr; }
		inline bool		operator!=(const Self& _x) const { return ptr != _x.ptr; }

		inline Self&		operator+(int _x) { for (; _x > 0; --_x) ptr = ptr->m_next; return *this; }
		inline Self&		operator-(int _x) { for (; _x > 0; --_x) ptr = ptr->m_prev; return *this; }

		const Node* ptr;
	};

	template<typename Key>
	class list
	{
	public:
		typedef Key						value_type;
		typedef Key*						pointer;
		typedef const Key*					const_pointer;
		typedef Key&						reference;
		typedef const Key&					const_reference;

		typedef list_iterator<Key>				iterator;
		typedef list_const_iterator<Key>			const_iterator;
		typedef __stl::reverse_iterator<const_iterator>		const_reverse_iterator;
		typedef __stl::reverse_iterator<iterator>		reverse_iterator;
		typedef size_t						size_type;
		typedef ptrdiff_t					difference_type;

	protected:
		typedef list_node<Key>					Node;
		Node init;

		inline Node* m_create_node(const Key& _x) {
			Node* tmp = (Node*)malloc(sizeof(Node));
			tmp->m_data = _x;
			return tmp;
		}

		inline Node*			m_create_node() { return (Node*)malloc(sizeof(Node)); }
		inline void			m_clear() { this->erase(begin(), end()); }
		inline void			m_init() { this->init.m_next = this->init.m_prev = &this->init; }

		inline void			m_fill_insert(iterator _pos, size_type _n, const Key& _x) {
			for (; _n > 0; --_n) this->m_insert(_pos, _x);
		}

		inline void			m_insert(iterator _position, const value_type& _x) {
			this->m_create_node(_x)->hook(_position.ptr);
		}

		inline void			m_erase(iterator _position) {
			_position.ptr->unhook();
			free(_position.ptr);
		}

		template<typename __Int>
		inline void			m_insert_dispatch(iterator _pos, __Int _n, __Int _x, __stl::true_type) {
			this->m_fill_insert(_pos, static_cast<size_type>(_n), static_cast<Key>(_x));
		}

		template<typename Iter>
		inline void			m_insert_dispatch(iterator _pos, Iter _first, Iter _last, __stl::false_type) {
			for (; _first != _last; ++_first) this->m_insert(_pos, *_first);
		}

		inline void			m_transfer(iterator _position, iterator _first, iterator _last) {
			if (_position != _last) {
				_last.ptr->m_prev->m_next = _position.ptr;
				_first.ptr->m_prev->m_next = _last.ptr;
				_position.ptr->m_prev->m_next = _first.ptr;

				Node* tmp = _position.ptr->m_prev;
				_position.ptr->m_prev = _last.ptr->m_prev;
				_last.ptr->m_prev = _first.ptr->m_prev;
				_first.ptr->m_prev = tmp;
			}
		}

	public:
		explicit list() : init(*m_create_node()) { m_init(); }
		explicit list(size_type _n) : init(*m_create_node()) { m_init(); this->insert(begin(), _n, Key()); }
		list(size_type _n, const Key& _value) : init(*m_create_node()) { m_init(); this->insert(begin(), _n, _value); }
		list(const list& _x) : init(*m_create_node()) { m_init(); this->insert(begin(), _x.begin(), _x.end()); }

		template<typename Iter>
		list(Iter _first, Iter _last) : init(*m_create_node()) { m_init(); this->insert(begin(), _first, _last); }

		~list() {
			/*Node* node, *tmp = &this->init;
			while (tmp) {
			node = tmp->m_next;
			delete node;
			}*/
		}

		/* Iterator operations */
		inline iterator			begin() { return (iterator)this->init.m_next; }
		inline const_iterator		cbegin() const { return (iterator)this->init.m_next; }
		inline iterator			end() { return (iterator)&this->init; }
		inline const_iterator		cend() const { return (iterator)&this->init; }
		inline reverse_iterator		rbegin() { return reverse_iterator(end()); }
		inline const_reverse_iterator	crbegin() const { return const_reverse_iterator(cend()); }
		inline reverse_iterator		rend() { return reverse_iterator(begin()); }
		inline const_reverse_iterator	crend() const { return const_reverse_iterator(cbegin()); }

		/* Size Operations */
		inline bool			empty() const { return this->init.m_next == &this->init; }
		inline size_type		size() const { return __stl::distance(begin(), end()); }
		inline size_type		max_size() const { return size_type(-1); }

		/* Element access */
		inline reference		front() { return *begin(); }
		inline const_reference		front() const { return *begin(); }
		inline reference		back() { return *(--end()); }
		inline const_reference		back() const { return *(--end()); }

		/* Modifiers */
		inline void			push_front(const Key& _x) { this->m_insert(begin(), _x); }
		inline void			pop_front() { this->m_erase(begin()); }
		inline void			push_back(const Key& _x) { this->m_insert(end(), _x); }
		inline void			pop_back() { this->m_erase(this->init.m_prev); }

		inline iterator			insert(iterator _pos, const Key& _x) { this->m_insert(_pos, _x); return --_pos; }
		inline void			insert(iterator _pos, size_type _n, const Key& _x) { this->m_fill_insert(_pos, _n, _x); }

		template<typename Iter>
		inline void			insert(iterator _pos, Iter _first, Iter _last) { this->m_insert_dispatch(_position, _first, _last, __stl::is_integral<Iter>::value); }

		inline iterator			erase(iterator _pos) { this->m_erase(_pos++); return _pos; }
		inline iterator			erase(iterator _first, iterator _last) { while (_first != _last) _first = erase(_first); return _last; }
		inline void			clear() { this->m_clear(); this->m_init(); }

		inline void			remove(const Key& _value) {
			for (iterator it = begin(); it != end(); ++it) {
				if (it.ptr->m_data == _value)
					it = this->erase(it);
			}
		}

		template <class Predicate>
		inline void			remove_if(Predicate _pred) {
			for (iterator it = begin(); it != end(); ++it) {
				if (_pred(*it))
					it = this->erase(it);

				// Fix last item delete
				if (_pred(back())) pop_back();
			}
		}

		/* Operators */
		inline bool operator==(const list& _x) {
			const_iterator end1 = end();
			const_iterator end2 = _x.end();

			const_iterator it1 = begin();
			const_iterator it2 = _x.begin();
			while (it1 != end1 && it2 != end2 && *it1 == *it2) {
				++it1;
				++it2;
			}

			return it1 == end1 && it2 == end2;
		}

		inline bool operator<(const list& _x) { return __stl::lexicographical_compare(_x.begin(), _x.end(), begin(), end()); }
		inline bool operator>(const list& _x) { return _x < *this; }
		inline bool operator!=(const list<Key>& _x) { return !(_x == *this); }
		inline bool operator<=(const list<Key>& _x) { return !(_x < *this); }
		inline bool operator>=(const list<Key>& _x) { return !(*this < _x); }
	};
__ztl_namespace_end

#endif /* _list_hpp_1337420 */
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2016 RISC-V Foundation
 * Copyright (c) 2016 The University of Virginia
 * Copyright (c) 2018 TU Dresden
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "arch/riscv/faults.hh"

#include "arch/riscv/fs_workload.hh"
#include "arch/riscv/isa.hh"
#include "arch/riscv/registers.hh"
#include "arch/riscv/utility.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#include "sim/debug.hh"
#include "sim/full_system.hh"

namespace RiscvISA
{

void
RiscvFault::invokeSE(ThreadContext *tc, const StaticInstPtr &inst)
{
    panic("Fault %s encountered at pc 0x%016llx.", name(), tc->pcState().pc());
}

void
RiscvFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
{
    PCState pcState = tc->pcState();

    if (FullSystem) {
        PrivilegeMode pp = (PrivilegeMode)tc->readMiscReg(MISCREG_PRV);
        PrivilegeMode prv = PRV_M;
        STATUS status = tc->readMiscReg(MISCREG_STATUS);

        // Set fault handler privilege mode
        if (isInterrupt()) {
            if (pp != PRV_M &&
                bits(tc->readMiscReg(MISCREG_MIDELEG), _code) != 0) {
                prv = PRV_S;
            }
            if (pp == PRV_U &&
                bits(tc->readMiscReg(MISCREG_SIDELEG), _code) != 0) {
                prv = PRV_U;
            }
        } else {
            if (pp != PRV_M &&
                bits(tc->readMiscReg(MISCREG_MEDELEG), _code) != 0) {
                prv = PRV_S;
            }
            if (pp == PRV_U &&
                bits(tc->readMiscReg(MISCREG_SEDELEG), _code) != 0) {
                prv = PRV_U;
            }
        }

        // Set fault registers and status
        MiscRegIndex cause, epc, tvec, tval;
        switch (prv) {
          case PRV_U:
            cause = MISCREG_UCAUSE;
            epc = MISCREG_UEPC;
            tvec = MISCREG_UTVEC;
            tval = MISCREG_UTVAL;

            status.upie = status.uie;
            status.uie = 0;
            break;
          case PRV_S:
            cause = MISCREG_SCAUSE;
            epc = MISCREG_SEPC;
            tvec = MISCREG_STVEC;
            tval = MISCREG_STVAL;

            status.spp = pp;
            status.spie = status.sie;
            status.sie = 0;
            break;
          case PRV_M:
            cause = MISCREG_MCAUSE;
            epc = MISCREG_MEPC;
            tvec = MISCREG_MTVEC;
            tval = MISCREG_MTVAL;

            status.mpp = pp;
            status.mpie = status.sie;
            status.mie = 0;
            break;
          default:
            panic("Unknown privilege mode %d.", prv);
            break;
        }

        // Set fault cause, privilege, and return PC
        tc->setMiscReg(cause,
                       (isInterrupt() << (sizeof(uint64_t) * 4 - 1)) | _code);
        tc->setMiscReg(epc, tc->instAddr());
        tc->setMiscReg(tval, trap_value());
        tc->setMiscReg(MISCREG_PRV, prv);
        tc->setMiscReg(MISCREG_STATUS, status);

        // Set PC to fault handler address
        Addr addr = tc->readMiscReg(tvec) >> 2;
        if (isInterrupt() && bits(tc->readMiscReg(tvec), 1, 0) == 1)
            addr += 4 * _code;
        pcState.set(addr);
    } else {
        invokeSE(tc, inst);
        advancePC(pcState, inst);
    }
    tc->pcState(pcState);
}

void Reset::invoke(ThreadContext *tc, const StaticInstPtr &inst)
{
    tc->setMiscReg(MISCREG_PRV, PRV_M);
    STATUS status = tc->readMiscReg(MISCREG_STATUS);
    status.mie = 0;
    status.mprv = 0;
    tc->setMiscReg(MISCREG_STATUS, status);
    tc->setMiscReg(MISCREG_MCAUSE, 0);

    // Advance the PC to the implementation-defined reset vector
    auto workload = dynamic_cast<FsWorkload *>(tc->getSystemPtr()->workload);
    PCState pc = workload->resetVect();
    tc->pcState(pc);
}

void
UnknownInstFault::invokeSE(ThreadContext *tc, const StaticInstPtr &inst)
{
    panic("Unknown instruction 0x%08x at pc 0x%016llx", inst->machInst,
        tc->pcState().pc());
}

void
IllegalInstFault::invokeSE(ThreadContext *tc, const StaticInstPtr &inst)
{
    panic("Illegal instruction 0x%08x at pc 0x%016llx: %s", inst->machInst,
        tc->pcState().pc(), reason.c_str());
}

void
UnimplementedFault::invokeSE(ThreadContext *tc,
        const StaticInstPtr &inst)
{
    panic("Unimplemented instruction %s at pc 0x%016llx", instName,
        tc->pcState().pc());
}

void
IllegalFrmFault::invokeSE(ThreadContext *tc, const StaticInstPtr &inst)
{
    panic("Illegal floating-point rounding mode 0x%x at pc 0x%016llx.",
            frm, tc->pcState().pc());
}

void
BreakpointFault::invokeSE(ThreadContext *tc, const StaticInstPtr &inst)
{
    schedRelBreak(0);
}

void
SyscallFault::invokeSE(ThreadContext *tc, const StaticInstPtr &inst)
{
    Fault *fault = NoFault;
    tc->syscall(fault);
}

} // namespace RiscvISA
<commit_msg>arch-riscv: print information about faults.<commit_after>/*
 * Copyright (c) 2016 RISC-V Foundation
 * Copyright (c) 2016 The University of Virginia
 * Copyright (c) 2018 TU Dresden
 * Copyright (c) 2020 Barkhausen Institut
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "arch/riscv/faults.hh"

#include "arch/riscv/fs_workload.hh"
#include "arch/riscv/isa.hh"
#include "arch/riscv/registers.hh"
#include "arch/riscv/utility.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#include "debug/Fault.hh"
#include "sim/debug.hh"
#include "sim/full_system.hh"

namespace RiscvISA
{

void
RiscvFault::invokeSE(ThreadContext *tc, const StaticInstPtr &inst)
{
    panic("Fault %s encountered at pc 0x%016llx.", name(), tc->pcState().pc());
}

void
RiscvFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
{
    PCState pcState = tc->pcState();

    DPRINTFS(Fault, tc->getCpuPtr(), "Fault (%s) at PC: %s\n",
             name(), pcState);

    if (FullSystem) {
        PrivilegeMode pp = (PrivilegeMode)tc->readMiscReg(MISCREG_PRV);
        PrivilegeMode prv = PRV_M;
        STATUS status = tc->readMiscReg(MISCREG_STATUS);

        // Set fault handler privilege mode
        if (isInterrupt()) {
            if (pp != PRV_M &&
                bits(tc->readMiscReg(MISCREG_MIDELEG), _code) != 0) {
                prv = PRV_S;
            }
            if (pp == PRV_U &&
                bits(tc->readMiscReg(MISCREG_SIDELEG), _code) != 0) {
                prv = PRV_U;
            }
        } else {
            if (pp != PRV_M &&
                bits(tc->readMiscReg(MISCREG_MEDELEG), _code) != 0) {
                prv = PRV_S;
            }
            if (pp == PRV_U &&
                bits(tc->readMiscReg(MISCREG_SEDELEG), _code) != 0) {
                prv = PRV_U;
            }
        }

        // Set fault registers and status
        MiscRegIndex cause, epc, tvec, tval;
        switch (prv) {
          case PRV_U:
            cause = MISCREG_UCAUSE;
            epc = MISCREG_UEPC;
            tvec = MISCREG_UTVEC;
            tval = MISCREG_UTVAL;

            status.upie = status.uie;
            status.uie = 0;
            break;
          case PRV_S:
            cause = MISCREG_SCAUSE;
            epc = MISCREG_SEPC;
            tvec = MISCREG_STVEC;
            tval = MISCREG_STVAL;

            status.spp = pp;
            status.spie = status.sie;
            status.sie = 0;
            break;
          case PRV_M:
            cause = MISCREG_MCAUSE;
            epc = MISCREG_MEPC;
            tvec = MISCREG_MTVEC;
            tval = MISCREG_MTVAL;

            status.mpp = pp;
            status.mpie = status.sie;
            status.mie = 0;
            break;
          default:
            panic("Unknown privilege mode %d.", prv);
            break;
        }

        // Set fault cause, privilege, and return PC
        tc->setMiscReg(cause,
                       (isInterrupt() << (sizeof(uint64_t) * 4 - 1)) | _code);
        tc->setMiscReg(epc, tc->instAddr());
        tc->setMiscReg(tval, trap_value());
        tc->setMiscReg(MISCREG_PRV, prv);
        tc->setMiscReg(MISCREG_STATUS, status);

        // Set PC to fault handler address
        Addr addr = tc->readMiscReg(tvec) >> 2;
        if (isInterrupt() && bits(tc->readMiscReg(tvec), 1, 0) == 1)
            addr += 4 * _code;
        pcState.set(addr);
    } else {
        invokeSE(tc, inst);
        advancePC(pcState, inst);
    }
    tc->pcState(pcState);
}

void Reset::invoke(ThreadContext *tc, const StaticInstPtr &inst)
{
    tc->setMiscReg(MISCREG_PRV, PRV_M);
    STATUS status = tc->readMiscReg(MISCREG_STATUS);
    status.mie = 0;
    status.mprv = 0;
    tc->setMiscReg(MISCREG_STATUS, status);
    tc->setMiscReg(MISCREG_MCAUSE, 0);

    // Advance the PC to the implementation-defined reset vector
    auto workload = dynamic_cast<FsWorkload *>(tc->getSystemPtr()->workload);
    PCState pc = workload->resetVect();
    tc->pcState(pc);
}

void
UnknownInstFault::invokeSE(ThreadContext *tc, const StaticInstPtr &inst)
{
    panic("Unknown instruction 0x%08x at pc 0x%016llx", inst->machInst,
        tc->pcState().pc());
}

void
IllegalInstFault::invokeSE(ThreadContext *tc, const StaticInstPtr &inst)
{
    panic("Illegal instruction 0x%08x at pc 0x%016llx: %s", inst->machInst,
        tc->pcState().pc(), reason.c_str());
}

void
UnimplementedFault::invokeSE(ThreadContext *tc,
        const StaticInstPtr &inst)
{
    panic("Unimplemented instruction %s at pc 0x%016llx", instName,
        tc->pcState().pc());
}

void
IllegalFrmFault::invokeSE(ThreadContext *tc, const StaticInstPtr &inst)
{
    panic("Illegal floating-point rounding mode 0x%x at pc 0x%016llx.",
            frm, tc->pcState().pc());
}

void
BreakpointFault::invokeSE(ThreadContext *tc, const StaticInstPtr &inst)
{
    schedRelBreak(0);
}

void
SyscallFault::invokeSE(ThreadContext *tc, const StaticInstPtr &inst)
{
    Fault *fault = NoFault;
    tc->syscall(fault);
}

} // namespace RiscvISA
<|endoftext|>


<commit_before>#include <stingray/toolkit/Factory.h>

#include <stingray/toolkit/any.h>

#include <stingray/app/application_context/AppChannel.h>
#include <stingray/app/application_context/ChannelList.h>
#include <stingray/app/scheduler/ScheduledEvents.h>
#include <stingray/app/tests/AutoFilter.h>
#include <stingray/app/zapper/User.h>
#include <stingray/hdmi/IHDMI.h>
#include <stingray/media/ImageFileMediaData.h>
#include <stingray/media/MediaInfoBase.h>
#include <stingray/media/Mp3MediaInfo.h>
#include <stingray/mpeg/Stream.h>
#include <stingray/parentalcontrol/AgeRating.h>
#ifdef PLATFORM_EMU
#	include <stingray/platform/emu/scanner/Channel.h>
#endif
#include <stingray/records/FileSystemRecord.h>
#include <stingray/scanner/DVBServiceId.h>
#include <stingray/scanner/DefaultDVBTBandInfo.h>
#include <stingray/scanner/DefaultMpegService.h>
#include <stingray/scanner/DefaultMpegStreamDescriptor.h>
#include <stingray/scanner/DefaultScanParams.h>
#include <stingray/scanner/DreCasGeographicRegion.h>
#include <stingray/scanner/IServiceId.h>
#include <stingray/scanner/TricolorGeographicRegion.h>
#include <stingray/scanner/TricolorScanParams.h>
#include <stingray/streams/RecordStreamMetaInfo.h>
#include <stingray/tuners/dvbs/Antenna.h>
#include <stingray/tuners/dvbs/DefaultDVBSTransport.h>
#include <stingray/tuners/dvbs/Satellite.h>
#include <stingray/tuners/dvbt/DefaultDVBTTransport.h>
#include <stingray/update/system/EraseFlashPartition.h>
#include <stingray/update/system/WriteFlashPartition.h>

/* WARNING! This is autogenerated file, DO NOT EDIT! */

namespace stingray { namespace Detail
{
	void Factory::RegisterTypes()
	{
#ifdef BUILD_SHARED_LIB
		/*nothing*/
#else
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::AppChannel);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(::stingray::Detail::any::ObjectHolder<stingray::app::AppChannelPtr>);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ChannelList);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::Alarm);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::CinemaHallScheduledViewing);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ContinuousScheduledEvent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::DeferredStandby);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::InfiniteScheduledEvent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ScheduledEvent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ScheduledRecord);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ScheduledViewing);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::AutoFilter);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::User);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(HDMIConfig);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(ImageFileMediaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(ImageFileMediaPreview);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(InMemoryImageMediaPreview);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MediaInfoBase);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(Mp3MediaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(mpeg::Stream);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(AgeRating);
#ifdef PLATFORM_EMU
		TOOLKIT_REGISTER_CLASS_EXPLICIT(emu::EmuServiceId);
#endif
#ifdef PLATFORM_EMU
		TOOLKIT_REGISTER_CLASS_EXPLICIT(emu::RadioChannel);
#endif
#ifdef PLATFORM_EMU
		TOOLKIT_REGISTER_CLASS_EXPLICIT(emu::StreamDescriptor);
#endif
#ifdef PLATFORM_EMU
		TOOLKIT_REGISTER_CLASS_EXPLICIT(emu::TVChannel);
#endif
		TOOLKIT_REGISTER_CLASS_EXPLICIT(FileSystemRecord);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DVBServiceId);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultDVBTBandInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultMpegRadioChannel);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultMpegService);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultMpegTVChannel);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegAudioStreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegDataCarouselStreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegPcrStreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegSubtitlesStreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegTeletextBasedSubtitlesStreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegTeletextStreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegVideoStreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultScanParams);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DreCasGeographicRegion);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(::stingray::Detail::any::ObjectHolder<stingray::ServiceId>);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TricolorGeographicRegion);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TricolorScanParams);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(RecordStreamMetaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(Antenna);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultDVBSTransport);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(Satellite);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultDVBTTransport);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(EraseFlashPartition);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(WriteFlashPartition);
#endif
	}
}}
<commit_msg>Added LybidScanParams and updated factory classes<commit_after>#include <stingray/toolkit/Factory.h>

#include <stingray/toolkit/any.h>

#include <stingray/app/application_context/AppChannel.h>
#include <stingray/app/application_context/ChannelList.h>
#include <stingray/app/scheduler/ScheduledEvents.h>
#include <stingray/app/tests/AutoFilter.h>
#include <stingray/app/zapper/User.h>
#include <stingray/hdmi/IHDMI.h>
#include <stingray/media/ImageFileMediaData.h>
#include <stingray/media/MediaInfoBase.h>
#include <stingray/media/Mp3MediaInfo.h>
#include <stingray/mpeg/Stream.h>
#include <stingray/parentalcontrol/AgeRating.h>
#ifdef PLATFORM_EMU
#	include <stingray/platform/emu/scanner/Channel.h>
#endif
#include <stingray/records/FileSystemRecord.h>
#include <stingray/scanner/DVBServiceId.h>
#include <stingray/scanner/DefaultDVBTBandInfo.h>
#include <stingray/scanner/DefaultMpegService.h>
#include <stingray/scanner/DefaultMpegStreamDescriptor.h>
#include <stingray/scanner/DefaultScanParams.h>
#include <stingray/scanner/DreCasGeographicRegion.h>
#include <stingray/scanner/IServiceId.h>
#include <stingray/scanner/LybidScanParams.h>
#include <stingray/scanner/TricolorGeographicRegion.h>
#include <stingray/scanner/TricolorScanParams.h>
#include <stingray/streams/RecordStreamMetaInfo.h>
#include <stingray/tuners/dvbs/Antenna.h>
#include <stingray/tuners/dvbs/DefaultDVBSTransport.h>
#include <stingray/tuners/dvbs/Satellite.h>
#include <stingray/tuners/dvbt/DefaultDVBTTransport.h>
#include <stingray/update/system/EraseFlashPartition.h>
#include <stingray/update/system/WriteFlashPartition.h>

/* WARNING! This is autogenerated file, DO NOT EDIT! */

namespace stingray { namespace Detail
{
	void Factory::RegisterTypes()
	{
#ifdef BUILD_SHARED_LIB
		/*nothing*/
#else
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::AppChannel);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(::stingray::Detail::any::ObjectHolder<stingray::app::AppChannelPtr>);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ChannelList);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::Alarm);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::CinemaHallScheduledViewing);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ContinuousScheduledEvent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::DeferredStandby);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::InfiniteScheduledEvent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ScheduledEvent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ScheduledRecord);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ScheduledViewing);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::AutoFilter);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::User);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(HDMIConfig);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(ImageFileMediaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(ImageFileMediaPreview);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(InMemoryImageMediaPreview);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MediaInfoBase);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(Mp3MediaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(mpeg::Stream);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(AgeRating);
#ifdef PLATFORM_EMU
		TOOLKIT_REGISTER_CLASS_EXPLICIT(emu::EmuServiceId);
#endif
#ifdef PLATFORM_EMU
		TOOLKIT_REGISTER_CLASS_EXPLICIT(emu::RadioChannel);
#endif
#ifdef PLATFORM_EMU
		TOOLKIT_REGISTER_CLASS_EXPLICIT(emu::StreamDescriptor);
#endif
#ifdef PLATFORM_EMU
		TOOLKIT_REGISTER_CLASS_EXPLICIT(emu::TVChannel);
#endif
		TOOLKIT_REGISTER_CLASS_EXPLICIT(FileSystemRecord);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DVBServiceId);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultDVBTBandInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultMpegRadioChannel);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultMpegService);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultMpegTVChannel);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegAudioStreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegDataCarouselStreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegPcrStreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegSubtitlesStreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegTeletextBasedSubtitlesStreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegTeletextStreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegVideoStreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultScanParams);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DreCasGeographicRegion);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(::stingray::Detail::any::ObjectHolder<stingray::ServiceId>);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(LybidScanParams);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TricolorGeographicRegion);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TricolorScanParams);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(RecordStreamMetaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(Antenna);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultDVBSTransport);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(Satellite);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultDVBTTransport);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(EraseFlashPartition);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(WriteFlashPartition);
#endif
	}
}}
<|endoftext|>


<commit_before>#include <limits>
#include <memory>

#include "catch.hpp"

#include "lattice.h"
#include "settings.h"

//! \brief Check 2D lattice D2Q9 case
TEST_CASE("2D Lattice weights are checked", "[LBM][Lattice][D2Q9]") {
  const lbmdem::Real Tolerance = 1.E-16;

  SECTION("D2Q9 lattice weights are checked") {
    const auto d2q9 = lbmdem::Lattice<2, 9>();

    REQUIRE(d2q9.weight( 0, 0) == Approx(4.0/9.0));

    REQUIRE(d2q9.weight( 1, 0) == Approx(1.0/9.0));
    REQUIRE(d2q9.weight( 0, 1) == Approx(1.0/9.0));
    REQUIRE(d2q9.weight(-1, 0) == Approx(1.0/9.0));
    REQUIRE(d2q9.weight( 0,-1) == Approx(1.0/9.0));

    REQUIRE(d2q9.weight( 1, 1) == Approx(1.0/36.0));
    REQUIRE(d2q9.weight( 1,-1) == Approx(1.0/36.0));
    REQUIRE(d2q9.weight(-1, 1) == Approx(1.0/36.0));
    REQUIRE(d2q9.weight(-1,-1) == Approx(1.0/36.0));
  }

  SECTION("D2Q9 lattice weights sum to 1") {
    const auto d2q9 = lbmdem::Lattice<2, 9>();

    lbmdem::Real sum = 0;
    for (int i = -1; i <= 1; ++i)
      for (int j = -1; j <= 1; ++j)
        sum += d2q9.weight(i,j);
    REQUIRE(sum == Approx(1.0));

    sum = 0;
    for (int i = 0; i < 9; ++i)
      sum += d2q9.weights.at(i);
    REQUIRE(sum == Approx(1.0));
  }

  SECTION("D2Q9 lattice weights are zero outside the stencil") {
    const auto d2q9 = lbmdem::Lattice<2, 9>();

    lbmdem::Real sum = 0;
    for (int i = -100; i <= 100; ++i)
      for (int j = -100; j <= 100; ++j)
        sum += d2q9.weight(i,j);
    REQUIRE(sum == Approx(1.0));
  }
}

//! \brief Check 3D lattice D3Q27 case
TEST_CASE("3D Lattice weights are checked", "[LBM][Lattice][D3Q27]") {
  const lbmdem::Real Tolerance = 1.E-16;

  SECTION("D3Q27 lattice weights are checked") {
    const auto d3q27 = lbmdem::Lattice<3, 27>();

    REQUIRE(d3q27.weight( 0, 0, 0) == Approx(8.0/27.0));

    REQUIRE(d3q27.weight( 1, 0, 0) == Approx(2.0/27.0));
    REQUIRE(d3q27.weight( 0, 1, 0) == Approx(2.0/27.0));
    REQUIRE(d3q27.weight( 0, 0, 1) == Approx(2.0/27.0));
    REQUIRE(d3q27.weight(-1, 0, 0) == Approx(2.0/27.0));
    REQUIRE(d3q27.weight( 0,-1, 0) == Approx(2.0/27.0));
    REQUIRE(d3q27.weight( 0, 0,-1) == Approx(2.0/27.0));

    REQUIRE(d3q27.weight( 1, 1, 0) == Approx(1.0/54.0));
    REQUIRE(d3q27.weight( 1, 0, 1) == Approx(1.0/54.0));
    REQUIRE(d3q27.weight( 0, 1, 1) == Approx(1.0/54.0));
    REQUIRE(d3q27.weight(-1, 1, 0) == Approx(1.0/54.0));
    REQUIRE(d3q27.weight(-1, 0, 1) == Approx(1.0/54.0));
    REQUIRE(d3q27.weight( 0,-1, 1) == Approx(1.0/54.0));
    REQUIRE(d3q27.weight( 1,-1, 0) == Approx(1.0/54.0));
    REQUIRE(d3q27.weight( 1, 0,-1) == Approx(1.0/54.0));
    REQUIRE(d3q27.weight( 0, 1,-1) == Approx(1.0/54.0));
    REQUIRE(d3q27.weight(-1,-1, 0) == Approx(1.0/54.0));
    REQUIRE(d3q27.weight(-1, 0,-1) == Approx(1.0/54.0));
    REQUIRE(d3q27.weight( 0,-1,-1) == Approx(1.0/54.0));

    REQUIRE(d3q27.weight( 1, 1, 1) == Approx(1.0/216.0));
    REQUIRE(d3q27.weight( 1, 1, 1) == Approx(1.0/216.0));
    REQUIRE(d3q27.weight( 1, 1, 1) == Approx(1.0/216.0));
    REQUIRE(d3q27.weight(-1,-1,-1) == Approx(1.0/216.0));
    REQUIRE(d3q27.weight(-1,-1,-1) == Approx(1.0/216.0));
    REQUIRE(d3q27.weight(-1,-1,-1) == Approx(1.0/216.0));
  }

  SECTION("D3Q27 lattice weights sum to 1") {
    const auto d3q27 = lbmdem::Lattice<3, 27>();

    lbmdem::Real sum = 0;
    for (int i = -1; i <= 1; ++i)
      for (int j = -1; j <= 1; ++j)
        for (int k = -1; k <= 1; ++k)
          sum += d3q27.weight(i,j,k);
    REQUIRE(sum == Approx(1.0));

    sum = 0;
    for (int i = 0; i < 27; ++i)
      sum += d3q27.weights.at(i);
    REQUIRE(sum == Approx(1.0));
  }

  SECTION("D3Q27 lattice weights are zero outside the stencil") {
    const auto d3q27 = lbmdem::Lattice<3, 27>();

    lbmdem::Real sum = 0;
    for (int i = -100; i <= 100; ++i)
      for (int j = -100; j <= 100; ++j)
        for (int k = -100; k <= 100; ++k)
          sum += d3q27.weight(i,j,k);
    REQUIRE(sum == Approx(1.0));
  }
}
<commit_msg>add tests for D3Q19 lattice weights<commit_after>#include <limits>
#include <memory>

#include "catch.hpp"

#include "lattice.h"
#include "settings.h"

//! \brief Check 2D lattice D2Q9 case
TEST_CASE("2D Lattice weights are checked", "[LBM][Lattice][D2Q9]") {
  const lbmdem::Real Tolerance = 1.E-16;

  SECTION("D2Q9 lattice weights are checked") {
    const auto d2q9 = lbmdem::Lattice<2, 9>();

    REQUIRE(d2q9.weight( 0, 0) == Approx(4.0/9.0));

    REQUIRE(d2q9.weight( 1, 0) == Approx(1.0/9.0));
    REQUIRE(d2q9.weight( 0, 1) == Approx(1.0/9.0));
    REQUIRE(d2q9.weight(-1, 0) == Approx(1.0/9.0));
    REQUIRE(d2q9.weight( 0,-1) == Approx(1.0/9.0));

    REQUIRE(d2q9.weight( 1, 1) == Approx(1.0/36.0));
    REQUIRE(d2q9.weight( 1,-1) == Approx(1.0/36.0));
    REQUIRE(d2q9.weight(-1, 1) == Approx(1.0/36.0));
    REQUIRE(d2q9.weight(-1,-1) == Approx(1.0/36.0));
  }

  SECTION("D2Q9 lattice weights sum to 1") {
    const auto d2q9 = lbmdem::Lattice<2, 9>();

    lbmdem::Real sum = 0;
    for (int i = -1; i <= 1; ++i)
      for (int j = -1; j <= 1; ++j)
        sum += d2q9.weight(i,j);
    REQUIRE(sum == Approx(1.0));

    sum = 0;
    for (int i = 0; i < 9; ++i)
      sum += d2q9.weights.at(i);
    REQUIRE(sum == Approx(1.0));
  }

  SECTION("D2Q9 lattice weights are zero outside the stencil") {
    const auto d2q9 = lbmdem::Lattice<2, 9>();

    lbmdem::Real sum = 0;
    for (int i = -100; i <= 100; ++i)
      for (int j = -100; j <= 100; ++j)
        sum += d2q9.weight(i,j);
    REQUIRE(sum == Approx(1.0));
  }
}

TEST_CASE("D3Q27 Lattice weights are checked", "[LBM][Lattice][D3Q19]") {
  SECTION("D3Q27 lattice weights sum to 1") {
    const auto d3q19 = lbmdem::Lattice<3, 19>();

    lbmdem::Real sum = 0;
    for (int i = -1; i <= 1; ++i)
      for (int j = -1; j <= 1; ++j)
        for (int k = -1; k <= 1; ++k)
          sum += d3q19.weight(i,j,k);
    REQUIRE(sum == Approx(1.0));

    sum = 0;
    for (int i = 0; i < 19; ++i)
      sum += d3q19.weights.at(i);
    REQUIRE(sum == Approx(1.0));
  }

  SECTION("D3Q19 lattice weights are zero outside the stencil") {
    const auto d3q19 = lbmdem::Lattice<3, 19>();

    lbmdem::Real sum = 0;
    for (int i = -100; i <= 100; ++i)
      for (int j = -100; j <= 100; ++j)
        for (int k = -100; k <= 100; ++k)
          sum += d3q19.weight(i,j,k);
    REQUIRE(sum == Approx(1.0));
  }
}

//! \brief Check 3D lattice D3Q27 case
TEST_CASE("DQ27 Lattice weights are checked", "[LBM][Lattice][D3Q27]") {
  const lbmdem::Real Tolerance = 1.E-16;

  SECTION("D3Q27 lattice weights are checked") {
    const auto d3q27 = lbmdem::Lattice<3, 27>();

    REQUIRE(d3q27.weight( 0, 0, 0) == Approx(8.0/27.0));

    REQUIRE(d3q27.weight( 1, 0, 0) == Approx(2.0/27.0));
    REQUIRE(d3q27.weight( 0, 1, 0) == Approx(2.0/27.0));
    REQUIRE(d3q27.weight( 0, 0, 1) == Approx(2.0/27.0));
    REQUIRE(d3q27.weight(-1, 0, 0) == Approx(2.0/27.0));
    REQUIRE(d3q27.weight( 0,-1, 0) == Approx(2.0/27.0));
    REQUIRE(d3q27.weight( 0, 0,-1) == Approx(2.0/27.0));

    REQUIRE(d3q27.weight( 1, 1, 0) == Approx(1.0/54.0));
    REQUIRE(d3q27.weight( 1, 0, 1) == Approx(1.0/54.0));
    REQUIRE(d3q27.weight( 0, 1, 1) == Approx(1.0/54.0));
    REQUIRE(d3q27.weight(-1, 1, 0) == Approx(1.0/54.0));
    REQUIRE(d3q27.weight(-1, 0, 1) == Approx(1.0/54.0));
    REQUIRE(d3q27.weight( 0,-1, 1) == Approx(1.0/54.0));
    REQUIRE(d3q27.weight( 1,-1, 0) == Approx(1.0/54.0));
    REQUIRE(d3q27.weight( 1, 0,-1) == Approx(1.0/54.0));
    REQUIRE(d3q27.weight( 0, 1,-1) == Approx(1.0/54.0));
    REQUIRE(d3q27.weight(-1,-1, 0) == Approx(1.0/54.0));
    REQUIRE(d3q27.weight(-1, 0,-1) == Approx(1.0/54.0));
    REQUIRE(d3q27.weight( 0,-1,-1) == Approx(1.0/54.0));

    REQUIRE(d3q27.weight( 1, 1, 1) == Approx(1.0/216.0));
    REQUIRE(d3q27.weight( 1, 1, 1) == Approx(1.0/216.0));
    REQUIRE(d3q27.weight( 1, 1, 1) == Approx(1.0/216.0));
    REQUIRE(d3q27.weight(-1,-1,-1) == Approx(1.0/216.0));
    REQUIRE(d3q27.weight(-1,-1,-1) == Approx(1.0/216.0));
    REQUIRE(d3q27.weight(-1,-1,-1) == Approx(1.0/216.0));
  }

  SECTION("D3Q27 lattice weights sum to 1") {
    const auto d3q27 = lbmdem::Lattice<3, 27>();

    lbmdem::Real sum = 0;
    for (int i = -1; i <= 1; ++i)
      for (int j = -1; j <= 1; ++j)
        for (int k = -1; k <= 1; ++k)
          sum += d3q27.weight(i,j,k);
    REQUIRE(sum == Approx(1.0));

    sum = 0;
    for (int i = 0; i < 27; ++i)
      sum += d3q27.weights.at(i);
    REQUIRE(sum == Approx(1.0));
  }

  SECTION("D3Q27 lattice weights are zero outside the stencil") {
    const auto d3q27 = lbmdem::Lattice<3, 27>();

    lbmdem::Real sum = 0;
    for (int i = -100; i <= 100; ++i)
      for (int j = -100; j <= 100; ++j)
        for (int k = -100; k <= 100; ++k)
          sum += d3q27.weight(i,j,k);
    REQUIRE(sum == Approx(1.0));
  }
}
<|endoftext|>


<commit_before>/*
Copyright 2015 University of Auckland

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.Some license of other
*/

#include "gtest/gtest.h"

#include <libcellml>

TEST(Maths, appendAndGetMathString) {
    std::string mathString =
    "<math xmlns=\"http://www.w3.org/1998/Math/MathML\"/>";
    libcellml::Component c;
    c.appendMathString(mathString);
    EXPECT_EQ(mathString, c.getMathString());
}

TEST(Maths, appendAndSerialiseMathStringComponent) {
    const std::string e =
    "<component>"
      "<math xmlns=\"http://www.w3.org/1998/Math/MathML\"/>"
    "</component>";
    std::string mathString =
    "<math xmlns=\"http://www.w3.org/1998/Math/MathML\"/>";
    libcellml::Component c;
    c.appendMathString(mathString);
    std::string a = c.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
}

TEST(Maths, appendAndRemoveMathStringComponent) {
    const std::string e =
    "<component/>";
    std::string mathString =
    "<math xmlns=\"http://www.w3.org/1998/Math/MathML\"/>";
    libcellml::Component c;
    c.appendMathString(mathString);
    c.removeMathString();
    std::string a = c.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
}

TEST(Maths, appendAndSerialiseMathStringModel) {
    const std::string e =
    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
    "<model xmlns=\"http://www.cellml.org/cellml/1.2#\">"
      "<component>"
        "<math xmlns=\"http://www.w3.org/1998/Math/MathML\"/>"
      "</component>"
    "</model>";
    std::string mathString =
    "<math xmlns=\"http://www.w3.org/1998/Math/MathML\"/>";
    libcellml::Component m;
    libcellml::ComponentPtr c = std::make_shared<libcellml::Component>();
    m.addComponent(c);
    c->appendMathString(mathString);
    std::string a = m.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
}

TEST(Maths, modelWithTwoVariablesAndTwoInvalidMathStrings) {
    const std::string e =
    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
    "<model xmlns=\"http://www.cellml.org/cellml/1.2#\">"
      "<component name=\"component\">"
        "<variable name=\"variable1\"/>"
        "<variable name=\"variable2\"/>"
        "<math xmlns=\"http://www.w3.org/1998/Math/MathML\"/>"
        "<math xmlns=\"http://www.w3.org/1998/Math/MathML\"/>"
      "</component>"
    "</model>";
    std::string mathString =
    "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">";
    libcellml::Model m;
    libcellml::ComponentPtr c = std::make_shared<libcellml::Component>();
    libcellml::VariablePtr v1 = std::make_shared<libcellml::Variable>();
    libcellml::VariablePtr v2 = std::make_shared<libcellml::Variable>();
    c->setName("component");
    v1->setName("variable1");
    v2->setName("variable2");
    c->addVariable(v1);
    c->addVariable(v2);
    c->appendMathString(mathString);
    c->appendMathString(mathString);
    m.addComponent(c);
    std::string a = m.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
}

// 1.xiii.a
TEST(Maths, modelWithTwoVariablesWithInitialValuesAndInvalidMathString) {
    const std::string e =
    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
    "<model xmlns=\"http://www.cellml.org/cellml/1.2#\">"
      "<component name=\"component\">"
        "<variable name=\"variable1\" initial_value=\"1.0\"/>"
        "<variable name=\"variable2\" initial_value=\"-1.0\"/>"
        "<math xmlns=\"http://www.w3.org/1998/Math/MathML\"/>";
      "</component>"
    "</model>";
    std::string mathString =
    "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">";
    libcellml::Model m;
    libcellml::ComponentPtr c = std::make_shared<libcellml::Component>();
    libcellml::VariablePtr v1 = std::make_shared<libcellml::Variable>();
    libcellml::VariablePtr v2 = std::make_shared<libcellml::Variable>();
    c->setName("component");
    v1->setName("variable1");
    v2->setName("variable2");
    v1->setInitialValue("1.0");
    v2->setInitialValue("-1.0");
    c->addVariable(v1);
    c->addVariable(v2);
    c->appendMathString(mathString);
    m.addComponent(c);
    std::string a = m.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
}

TEST(Maths, modelWithTwoVariablesWithInitialValuesAndValidMathString) {
    const std::string e =
    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
    "<model xmlns=\"http://www.cellml.org/cellml/1.2#\">"
      "<component name=\"component\">"
        "<variable name=\"A\" initial_value=\"1.0\"/>"
        "<variable name=\"B\" initial_value=\"-1.0\"/>"
        "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">"
          "<apply>"
             "<plus/>"
             "<ci>A</ci>"
             "<ci>B</ci>"
          "</apply>"
        "</math>"
      "</component>"
    "</model>";
    std::string mathString =
    "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">"
      "<apply>"
         "<plus/>"
         "<ci>A</ci>"
         "<ci>B</ci>"
      "</apply>"
    "</math>";
    libcellml::Model m;
    libcellml::ComponentPtr c = std::make_shared<libcellml::Component>();
    libcellml::VariablePtr v1 = std::make_shared<libcellml::Variable>();
    libcellml::VariablePtr v2 = std::make_shared<libcellml::Variable>();
    c->setName("component");
    v1->setName("A");
    v2->setName("B");
    v1->setInitialValue("1.0");
    v2->setInitialValue("-1.0");
    c->addVariable(v1);
    c->addVariable(v2);
    c->appendMathString(mathString);
    m.addComponent(c);
    std::string a = m.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
}

// 1.xiv.a
TEST(Maths, twoComponentsWithMathStringsAndConnection) {
    const std::string e =
    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
    "<model xmlns=\"http://www.cellml.org/cellml/1.2#\">"
      "<component name=\"component1\">"
        "<variable name=\"A1\"/>"
        "<variable name=\"B1\"/>"
        "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">"
          "<apply>"
             "<plus/>"
             "<ci>A1</ci>"
             "<ci>B1</ci>"
          "</apply>"
        "</math>"
      "</component>"
      "<component name=\"component2\">"
        "<variable name=\"A2\"/>"
        "<variable name=\"B2\"/>"
        "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">"
          "<apply>"
             "<plus/>"
             "<ci>A2</ci>"
             "<ci>B2</ci>"
          "</apply>"
        "</math>"
      "</component>"
      "<connection>"
        "<map_components component_1=\"component1\" component_2=\"component2\"/>"
        "<map_variables variable_1=\"A1\" variable_2=\"A2\"/>"
      "</connection>"
    "</model>";

    std::string mathString1 =
    "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">"
      "<apply>"
         "<plus/>"
         "<ci>A1</ci>"
         "<ci>B1</ci>"
      "</apply>"
    "</math>";
    std::string mathString2 =
    "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">"
      "<apply>"
         "<plus/>"
         "<ci>A2</ci>"
         "<ci>B2</ci>"
      "</apply>"
    "</math>";

    libcellml::Model m;
    libcellml::ComponentPtr comp1 = std::make_shared<libcellml::Component>();
    libcellml::ComponentPtr comp2 = std::make_shared<libcellml::Component>();
    libcellml::VariablePtr v11 = std::make_shared<libcellml::Variable>();
    libcellml::VariablePtr v12 = std::make_shared<libcellml::Variable>();
    libcellml::VariablePtr v21 = std::make_shared<libcellml::Variable>();
    libcellml::VariablePtr v22 = std::make_shared<libcellml::Variable>();

    comp1->setName("component1");
    comp2->setName("component2");
    v11->setName("A1");
    v12->setName("B1");
    v21->setName("A2");
    v22->setName("B2");

    comp1->addVariable(v11);
    comp1->addVariable(v12);
    comp2->addVariable(v21);
    comp2->addVariable(v22);
    comp1->appendMathString(mathString1);
    comp2->appendMathString(mathString2);
    m.addComponent(comp1);
    m.addComponent(comp2);
    libcellml::Variable::addEquivalence(v11,v21);

    std::string a = m.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
}
<commit_msg>change math tests from 'A+B' to 'A+B=C'<commit_after>/*
Copyright 2015 University of Auckland

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.Some license of other
*/

#include "gtest/gtest.h"

#include <libcellml>

TEST(Maths, appendAndGetMathString) {
    std::string mathString =
    "<math xmlns=\"http://www.w3.org/1998/Math/MathML\"/>";
    libcellml::Component c;
    c.appendMathString(mathString);
    EXPECT_EQ(mathString, c.getMathString());
}

TEST(Maths, appendAndSerialiseMathStringComponent) {
    const std::string e =
    "<component>"
      "<math xmlns=\"http://www.w3.org/1998/Math/MathML\"/>"
    "</component>";
    std::string mathString =
    "<math xmlns=\"http://www.w3.org/1998/Math/MathML\"/>";
    libcellml::Component c;
    c.appendMathString(mathString);
    std::string a = c.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
}

TEST(Maths, appendAndRemoveMathStringComponent) {
    const std::string e =
    "<component/>";
    std::string mathString =
    "<math xmlns=\"http://www.w3.org/1998/Math/MathML\"/>";
    libcellml::Component c;
    c.appendMathString(mathString);
    c.removeMathString();
    std::string a = c.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
}

TEST(Maths, appendAndSerialiseMathStringModel) {
    const std::string e =
    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
    "<model xmlns=\"http://www.cellml.org/cellml/1.2#\">"
      "<component>"
        "<math xmlns=\"http://www.w3.org/1998/Math/MathML\"/>"
      "</component>"
    "</model>";
    std::string mathString =
    "<math xmlns=\"http://www.w3.org/1998/Math/MathML\"/>";
    libcellml::Component m;
    libcellml::ComponentPtr c = std::make_shared<libcellml::Component>();
    m.addComponent(c);
    c->appendMathString(mathString);
    std::string a = m.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
}

TEST(Maths, modelWithTwoVariablesAndTwoInvalidMathStrings) {
    const std::string e =
    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
    "<model xmlns=\"http://www.cellml.org/cellml/1.2#\">"
      "<component name=\"component\">"
        "<variable name=\"variable1\"/>"
        "<variable name=\"variable2\"/>"
        "<math xmlns=\"http://www.w3.org/1998/Math/MathML\"/>"
        "<math xmlns=\"http://www.w3.org/1998/Math/MathML\"/>"
      "</component>"
    "</model>";
    std::string mathString =
    "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">";
    libcellml::Model m;
    libcellml::ComponentPtr c = std::make_shared<libcellml::Component>();
    libcellml::VariablePtr v1 = std::make_shared<libcellml::Variable>();
    libcellml::VariablePtr v2 = std::make_shared<libcellml::Variable>();
    c->setName("component");
    v1->setName("variable1");
    v2->setName("variable2");
    c->addVariable(v1);
    c->addVariable(v2);
    c->appendMathString(mathString);
    c->appendMathString(mathString);
    m.addComponent(c);
    std::string a = m.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
}

TEST(Maths, modelWithTwoVariablesWithInitialValuesAndInvalidMathString) {
    const std::string e =
    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
    "<model xmlns=\"http://www.cellml.org/cellml/1.2#\">"
      "<component name=\"component\">"
        "<variable name=\"variable1\" initial_value=\"1.0\"/>"
        "<variable name=\"variable2\" initial_value=\"-1.0\"/>"
        "<math xmlns=\"http://www.w3.org/1998/Math/MathML\"/>";
      "</component>"
    "</model>";
    std::string mathString =
    "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">";
    libcellml::Model m;
    libcellml::ComponentPtr c = std::make_shared<libcellml::Component>();
    libcellml::VariablePtr v1 = std::make_shared<libcellml::Variable>();
    libcellml::VariablePtr v2 = std::make_shared<libcellml::Variable>();
    c->setName("component");
    v1->setName("variable1");
    v2->setName("variable2");
    v1->setInitialValue("1.0");
    v2->setInitialValue("-1.0");
    c->addVariable(v1);
    c->addVariable(v2);
    c->appendMathString(mathString);
    m.addComponent(c);
    std::string a = m.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
}

// 1.xiii.a
TEST(Maths, modelWithTwoVariablesWithInitialValuesAndValidMathString) {
    const std::string e =
    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
    "<model xmlns=\"http://www.cellml.org/cellml/1.2#\">"
      "<component name=\"component\">"
        "<variable name=\"A\" initial_value=\"1.0\"/>"
        "<variable name=\"B\" initial_value=\"-1.0\"/>"
        "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">"
          "<apply><eq/>"
            "<ci>C</ci>"
            "<apply><plus/>"
              "<ci>A</ci>"
              "<ci>B</ci>"
            "</apply>"
          "</apply>"
        "</math>"
      "</component>"
    "</model>";
    std::string mathString =
    "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">"
      "<apply><eq/>"
        "<ci>C</ci>"
        "<apply><plus/>"
          "<ci>A</ci>"
          "<ci>B</ci>"
        "</apply>"
      "</apply>"
    "</math>";
    libcellml::Model m;
    libcellml::ComponentPtr c = std::make_shared<libcellml::Component>();
    libcellml::VariablePtr v1 = std::make_shared<libcellml::Variable>();
    libcellml::VariablePtr v2 = std::make_shared<libcellml::Variable>();
    c->setName("component");
    v1->setName("A");
    v2->setName("B");
    v1->setInitialValue("1.0");
    v2->setInitialValue("-1.0");
    c->addVariable(v1);
    c->addVariable(v2);
    c->appendMathString(mathString);
    m.addComponent(c);
    std::string a = m.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
}

// 1.xiv.a
TEST(Maths, twoComponentsWithMathStringsAndConnection) {
    const std::string e =
    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
    "<model xmlns=\"http://www.cellml.org/cellml/1.2#\">"
      "<component name=\"component1\">"
        "<variable name=\"A1\"/>"
        "<variable name=\"B1\"/>"
        "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">"
          "<apply><eq/>"
            "<ci>C1</ci>"
            "<apply><plus/>"
              "<ci>A1</ci>"
              "<ci>B1</ci>"
            "</apply>"
          "</apply>"
        "</math>"
      "</component>"
      "<component name=\"component2\">"
        "<variable name=\"A2\"/>"
        "<variable name=\"B2\"/>"
        "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">"
          "<apply><eq/>"
            "<ci>C2</ci>"
            "<apply><plus/>"
              "<ci>A2</ci>"
              "<ci>B2</ci>"
            "</apply>"
          "</apply>"
        "</math>"
      "</component>"
      "<connection>"
        "<map_components component_1=\"component1\" component_2=\"component2\"/>"
        "<map_variables variable_1=\"A1\" variable_2=\"A2\"/>"
      "</connection>"
    "</model>";

    std::string mathString1 =
    "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">"
      "<apply><eq/>"
        "<ci>C1</ci>"
        "<apply><plus/>"
          "<ci>A1</ci>"
          "<ci>B1</ci>"
        "</apply>"
      "</apply>"
    "</math>";
    std::string mathString2 =
    "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">"
      "<apply><eq/>"
        "<ci>C2</ci>"
        "<apply><plus/>"
          "<ci>A2</ci>"
          "<ci>B2</ci>"
        "</apply>"
      "</apply>"
    "</math>";

    libcellml::Model m;
    libcellml::ComponentPtr comp1 = std::make_shared<libcellml::Component>();
    libcellml::ComponentPtr comp2 = std::make_shared<libcellml::Component>();
    libcellml::VariablePtr v11 = std::make_shared<libcellml::Variable>();
    libcellml::VariablePtr v12 = std::make_shared<libcellml::Variable>();
    libcellml::VariablePtr v21 = std::make_shared<libcellml::Variable>();
    libcellml::VariablePtr v22 = std::make_shared<libcellml::Variable>();

    comp1->setName("component1");
    comp2->setName("component2");
    v11->setName("A1");
    v12->setName("B1");
    v21->setName("A2");
    v22->setName("B2");

    comp1->addVariable(v11);
    comp1->addVariable(v12);
    comp2->addVariable(v21);
    comp2->addVariable(v22);
    comp1->appendMathString(mathString1);
    comp2->appendMathString(mathString2);
    m.addComponent(comp1);
    m.addComponent(comp2);
    libcellml::Variable::addEquivalence(v11,v21);

    std::string a = m.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
}
<|endoftext|>


<commit_before>#pragma once
#include <planning/Path.hpp>
#include <Geometry2d/Point.hpp>
#include <Geometry2d/Segment.hpp>
#include <Geometry2d/CompositeShape.hpp>
#include <Configuration.hpp>

namespace Planning
{
	/**
	 * @brief Represents a motion path made up of a series of Paths.
	 *
	 * @details The path represents a function of position given time that the robot should follow.
	 * The path is made up of other Paths and can be made up of CompositePaths.
	 */
	class CompositePath: public Path
	{
		private:
			//Vector of Paths
			std::vector<std::unique_ptr<Path>> paths;

			/**
			 * Append the path to the end of the CompositePath
			 * The path passed in should not be refenced anywhere else.
			 */
			void append(Path *path);

			//Saving some variables to speed up computation
			float duration;

		public:
			/** default path is empty */
			CompositePath() {}

			/** constructors with one path */
			CompositePath(Path *path);
			CompositePath(std::unique_ptr<Path> path);

			/**
			 * Append the path to the end of the CompositePath
			 */
			void append(std::unique_ptr<Path> path);

			virtual bool evaluate(float t, Geometry2d::Point &targetPosOut, Geometry2d::Point &targetVelOut) const override;
			virtual bool hit(const Geometry2d::CompositeShape &shape, float startTime = 0) const override;
			virtual void draw(SystemState * const state, const QColor &color = Qt::black, const QString &layer = "Motion") const override;
			virtual float getDuration() const override;
			virtual std::unique_ptr<Path> subPath(float startTime = 0, float endTime = std::numeric_limits<float>::infinity()) const override;
			virtual boost::optional<Geometry2d::Point> destination() const override;
			virtual std::unique_ptr<Path> clone() const override;
	};
}
<commit_msg>Fix Tabs in CompositePath.hpp<commit_after>#pragma once
#include <planning/Path.hpp>
#include <Geometry2d/Point.hpp>
#include <Geometry2d/Segment.hpp>
#include <Geometry2d/CompositeShape.hpp>
#include <Configuration.hpp>

namespace Planning
{
	/**
	 * @brief Represents a motion path made up of a series of Paths.
	 *
	 * @details The path represents a function of position given time that the robot should follow.
	 * The path is made up of other Paths and can be made up of CompositePaths.
	 */
	class CompositePath: public Path
	{

	private:
		//Vector of Paths
		std::vector<std::unique_ptr<Path>> paths;

		/**
		 * Append the path to the end of the CompositePath
		 * The path passed in should not be refenced anywhere else.
		 */
		void append(Path *path);

		//Saving some variables to speed up computation
		float duration;

	public:
		/** default path is empty */
		CompositePath() {}

		/** constructors with one path */
		CompositePath(Path *path);
		CompositePath(std::unique_ptr<Path> path);

		/**
		 * Append the path to the end of the CompositePath
		 */
		void append(std::unique_ptr<Path> path);

		virtual bool evaluate(float t, Geometry2d::Point &targetPosOut, Geometry2d::Point &targetVelOut) const override;
		virtual bool hit(const Geometry2d::CompositeShape &shape, float startTime = 0) const override;
		virtual void draw(SystemState * const state, const QColor &color = Qt::black, const QString &layer = "Motion") const override;
		virtual float getDuration() const override;
		virtual std::unique_ptr<Path> subPath(float startTime = 0, float endTime = std::numeric_limits<float>::infinity()) const override;
		virtual boost::optional<Geometry2d::Point> destination() const override;
		virtual std::unique_ptr<Path> clone() const override;
	};
}
<|endoftext|>


<commit_before>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//
// $Id: glmesh.C,v 1.9 2002/12/20 20:14:36 anhi Exp $

#include <BALL/VIEW/GUI/PRIMITIV/glmesh.h>

namespace BALL
{
	namespace VIEW
	{

		GLMesh::GLMesh()
			throw()
			:	Mesh(),
				GLObject()
		{
		}

		GLMesh::GLMesh(const GLMesh& mesh, bool deep)
			throw()
			:	Mesh(mesh, deep),
				GLObject(mesh)
		{
		}

		GLMesh::GLMesh(const GeometricObject& geometric_object)
			throw()
			:	Mesh(geometric_object),
				GLObject()
		{
		}

		GLMesh::~GLMesh()
			throw()
		{
			#ifdef BALL_VIEW_DEBUG
				Log.info() << "Destructing object " << (void *)this << " of class " << RTTI::getName<GLMesh>() << endl;
			#endif

			destroy();
		}

		void GLMesh::clear()
			throw()
		{
			Mesh::clear();
			GLObject::clear();
		}

		void GLMesh::destroy()
			throw()
		{
			Mesh::destroy();
			GLObject::destroy();
		}

		void GLMesh::set(const GLMesh& mesh, bool deep)
			throw()
		{
			Mesh::set(mesh, deep);
			GLObject::set(mesh);
		}

		const GLMesh& GLMesh::operator = (const GLMesh& mesh)
			throw()
		{
			set(mesh);
			return *this;
		}

		void GLMesh::get(GLMesh& mesh, bool deep) const
			throw()
		{
			mesh.set(*this, deep);
		}

		void GLMesh::swap(GLMesh& mesh)
			throw()
		{
			Mesh::swap(mesh);
			GLObject::swap(mesh);
		}

		bool GLMesh::draw(bool with_names)
			throw()
		{
			if (hasProperty(GeometricObject::PROPERTY__OBJECT_HIDDEN) == true)
			{
				return true;
			}

			if (isSelected() == false)
			{
				glColor4ub((unsigned char)getColor().getRed(),
									 (unsigned char)getColor().getGreen(),
									 (unsigned char)getColor().getBlue(),
									 (unsigned char)getColor().getAlpha());
			}
			else
			{
				glColor4ub((unsigned char)BALL_SELECTED_COLOR.getRed(),
									 (unsigned char)BALL_SELECTED_COLOR.getGreen(),
									 (unsigned char)BALL_SELECTED_COLOR.getBlue(),
									 (unsigned char)BALL_SELECTED_COLOR.getAlpha());
			}

			if (with_names)
			{
				glLoadName(getGLPrimitiveManager()->getName(*this));
			}

			glPushMatrix();
			unsigned int precision;
			unsigned int mode;

			getDrawingModeAndPrecision(mode, precision);
			mode += GeometricObject::PROPERTY__DRAWING_MODE_DOTS;

			cout << mode << endl;

			// If we have only one color for the whole mesh, this can
			// be assigned efficiently
			if (colorList.size() < vertex.size())
			{
				if (colorList.size() == 0)
				{
					glColor4ub(255,255,255,255);
				}
				else
				{
					glColor4ub((unsigned char)colorList[0].getRed(),
										 (unsigned char)colorList[0].getGreen(),
										 (unsigned char)colorList[0].getBlue(),
										 (unsigned char)colorList[0].getAlpha());
				}

				Triangle t;
				Vector3 v, n;

				if (mode == GeometricObject::PROPERTY__DRAWING_MODE_DOTS)
				{
					glBegin(GL_POINTS);

					// draw the triangles with lines
					for (Size index = 0; index < triangle.size(); ++index)
					{
						t = triangle[index];

						v = vertex[t.v1];

						glVertex3f((GLfloat)v.x, (GLfloat)v.y, (GLfloat)v.z);
					}

					glEnd();
					// ------------------
				}
				else if (mode == GeometricObject::PROPERTY__DRAWING_MODE_WIREFRAME)
				{

					// draw the triangles with lines
					for (Size index = 0; index < triangle.size(); ++index)
					{
						glBegin(GL_LINE_STRIP);

						t = triangle[index];

						v = vertex[t.v1];

						glVertex3f((GLfloat)v.x, (GLfloat)v.y, (GLfloat)v.z);

						v = vertex[t.v2];

						glVertex3f((GLfloat)v.x, (GLfloat)v.y, (GLfloat)v.z);

						v = vertex[t.v3];

						glVertex3f((GLfloat)v.x, (GLfloat)v.y, (GLfloat)v.z);

						glEnd();
					}
					// ------------------
				}
				else
				{
					// draw the triangles
					for (Size index = 0; index < triangle.size(); ++index)
					{
						glBegin(GL_TRIANGLES);

						t = triangle[index];

						v = vertex[t.v1];
						n = normal[t.v1];

						glNormal3f((GLfloat)n.x, (GLfloat)n.y, (GLfloat)n.z);
						glVertex3f((GLfloat)v.x, (GLfloat)v.y, (GLfloat)v.z);

						v = vertex[t.v2];
						n = normal[t.v2];

						glNormal3f((GLfloat)n.x, (GLfloat)n.y, (GLfloat)n.z);
						glVertex3f((GLfloat)v.x, (GLfloat)v.y, (GLfloat)v.z);

						v = vertex[t.v3];
						n = normal[t.v3];

						glNormal3f((GLfloat)n.x, (GLfloat)n.y, (GLfloat)n.z);
						glVertex3f((GLfloat)v.x, (GLfloat)v.y, (GLfloat)v.z);

						glEnd();
					}
					// ------------------
				}
			}
			else // we have a different color for each vertex
			{
				unsigned int precision;
				unsigned int mode;

				getDrawingModeAndPrecision(mode, precision);

				Triangle t;
				Vector3 v, n;

				if (mode == GeometricObject::PROPERTY__DRAWING_MODE_DOTS)
				{
					glBegin(GL_POINTS);

					// draw the triangles with lines
					for (Size index = 0; index < triangle.size(); ++index)
					{
						t = triangle[index];

						v = vertex[t.v1];
						// set the color
						ColorRGBA col = colorList[t.v1];
						glColor4ub((unsigned char)col.getRed(),
	 						 				 (unsigned char)col.getGreen(),
											 (unsigned char)col.getBlue(),
											 (unsigned char)col.getAlpha());

						glVertex3f((GLfloat)v.x, (GLfloat)v.y, (GLfloat)v.z);
					}

					glEnd();
					// ------------------
				}
				else if (mode == GeometricObject::PROPERTY__DRAWING_MODE_WIREFRAME)
				{
					// draw the triangles with lines
					for (Size index = 0; index < triangle.size(); ++index)
					{
						glBegin(GL_LINE_STRIP);

						t = triangle[index];

						v = vertex[t.v1];

						ColorRGBA col = colorList[t.v1];
						glColor4ub((unsigned char)col.getRed(),
	 						 				 (unsigned char)col.getGreen(),
											 (unsigned char)col.getBlue(),
											 (unsigned char)col.getAlpha());

						glVertex3f((GLfloat)v.x, (GLfloat)v.y, (GLfloat)v.z);

						v = vertex[t.v2];

						col = colorList[t.v2];
						glColor4ub((unsigned char)col.getRed(),
	 						 				 (unsigned char)col.getGreen(),
											 (unsigned char)col.getBlue(),
											 (unsigned char)col.getAlpha());

						glVertex3f((GLfloat)v.x, (GLfloat)v.y, (GLfloat)v.z);

						v = vertex[t.v3];

						col = colorList[t.v3];
						glColor4ub((unsigned char)col.getRed(),
	 						 				 (unsigned char)col.getGreen(),
											 (unsigned char)col.getBlue(),
											 (unsigned char)col.getAlpha());

						glVertex3f((GLfloat)v.x, (GLfloat)v.y, (GLfloat)v.z);

						glEnd();
					}
					// ------------------
				}
				else
				{
					// draw the triangles
					for (Size index = 0; index < triangle.size(); ++index)
					{
						glBegin(GL_TRIANGLES);

						t = triangle[index];

						v = vertex[t.v1];
						n = normal[t.v1];
						ColorRGBA col = colorList[t.v1];
						glColor4ub((unsigned char)col.getRed(),
	 						 				 (unsigned char)col.getGreen(),
											 (unsigned char)col.getBlue(),
											 (unsigned char)col.getAlpha());

						glNormal3f((GLfloat)n.x, (GLfloat)n.y, (GLfloat)n.z);
						glVertex3f((GLfloat)v.x, (GLfloat)v.y, (GLfloat)v.z);

						v = vertex[t.v2];
						n = normal[t.v2];
						col = colorList[t.v2];
						glColor4ub((unsigned char)col.getRed(),
	 						 				 (unsigned char)col.getGreen(),
											 (unsigned char)col.getBlue(),
											 (unsigned char)col.getAlpha());

						glNormal3f((GLfloat)n.x, (GLfloat)n.y, (GLfloat)n.z);
						glVertex3f((GLfloat)v.x, (GLfloat)v.y, (GLfloat)v.z);

						v = vertex[t.v3];
						n = normal[t.v3];
						col = colorList[t.v3];
						glColor4ub((unsigned char)col.getRed(),
	 						 				 (unsigned char)col.getGreen(),
											 (unsigned char)col.getBlue(),
											 (unsigned char)col.getAlpha());

						glNormal3f((GLfloat)n.x, (GLfloat)n.y, (GLfloat)n.z);
						glVertex3f((GLfloat)v.x, (GLfloat)v.y, (GLfloat)v.z);

						glEnd();
					}
					// ------------------
				}
			}
			glPopMatrix();

			return true;
		}

		bool GLMesh::extract()
			throw()
		{
			return Mesh::extract();
		}

	} // namespace VIEW

} // namespace BALL
<commit_msg>*** empty log message ***<commit_after>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//
// $Id: glmesh.C,v 1.10 2002/12/22 13:08:03 oliver Exp $

#include <BALL/VIEW/GUI/PRIMITIV/glmesh.h>

namespace BALL
{
	namespace VIEW
	{

		GLMesh::GLMesh()
			throw()
			:	Mesh(),
				GLObject()
		{
		}

		GLMesh::GLMesh(const GLMesh& mesh, bool deep)
			throw()
			:	Mesh(mesh, deep),
				GLObject(mesh)
		{
		}

		GLMesh::GLMesh(const GeometricObject& geometric_object)
			throw()
			:	Mesh(geometric_object),
				GLObject()
		{
		}

		GLMesh::~GLMesh()
			throw()
		{
			#ifdef BALL_VIEW_DEBUG
				Log.info() << "Destructing object " << (void *)this << " of class " << RTTI::getName<GLMesh>() << endl;
			#endif

			destroy();
		}

		void GLMesh::clear()
			throw()
		{
			Mesh::clear();
			GLObject::clear();
		}

		void GLMesh::destroy()
			throw()
		{
			Mesh::destroy();
			GLObject::destroy();
		}

		void GLMesh::set(const GLMesh& mesh, bool deep)
			throw()
		{
			Mesh::set(mesh, deep);
			GLObject::set(mesh);
		}

		const GLMesh& GLMesh::operator = (const GLMesh& mesh)
			throw()
		{
			set(mesh);
			return *this;
		}

		void GLMesh::get(GLMesh& mesh, bool deep) const
			throw()
		{
			mesh.set(*this, deep);
		}

		void GLMesh::swap(GLMesh& mesh)
			throw()
		{
			Mesh::swap(mesh);
			GLObject::swap(mesh);
		}

		bool GLMesh::draw(bool with_names)
			throw()
		{
			if (hasProperty(GeometricObject::PROPERTY__OBJECT_HIDDEN) == true)
			{
				return true;
			}

			if (isSelected() == false)
			{
				glColor4ub((unsigned char)getColor().getRed(),
									 (unsigned char)getColor().getGreen(),
									 (unsigned char)getColor().getBlue(),
									 (unsigned char)getColor().getAlpha());
			}
			else
			{
				glColor4ub((unsigned char)BALL_SELECTED_COLOR.getRed(),
									 (unsigned char)BALL_SELECTED_COLOR.getGreen(),
									 (unsigned char)BALL_SELECTED_COLOR.getBlue(),
									 (unsigned char)BALL_SELECTED_COLOR.getAlpha());
			}

			if (with_names)
			{
				glLoadName(getGLPrimitiveManager()->getName(*this));
			}

			glPushMatrix();
			unsigned int precision;
			unsigned int mode;

			getDrawingModeAndPrecision(mode, precision);
			mode += GeometricObject::PROPERTY__DRAWING_MODE_DOTS;

			// If we have only one color for the whole mesh, this can
			// be assigned efficiently
			if (colorList.size() < vertex.size())
			{
				if (colorList.size() == 0)
				{
					glColor4ub(255,255,255,255);
				}
				else
				{
					glColor4ub((unsigned char)colorList[0].getRed(),
										 (unsigned char)colorList[0].getGreen(),
										 (unsigned char)colorList[0].getBlue(),
										 (unsigned char)colorList[0].getAlpha());
				}

				Triangle t;
				Vector3 v, n;

				if (mode == GeometricObject::PROPERTY__DRAWING_MODE_DOTS)
				{
					glBegin(GL_POINTS);

					// draw the triangles with lines
					for (Size index = 0; index < triangle.size(); ++index)
					{
						t = triangle[index];

						v = vertex[t.v1];

						glVertex3f((GLfloat)v.x, (GLfloat)v.y, (GLfloat)v.z);
					}

					glEnd();
					// ------------------
				}
				else if (mode == GeometricObject::PROPERTY__DRAWING_MODE_WIREFRAME)
				{

					// draw the triangles with lines
					for (Size index = 0; index < triangle.size(); ++index)
					{
						glBegin(GL_LINE_STRIP);

						t = triangle[index];

						v = vertex[t.v1];

						glVertex3f((GLfloat)v.x, (GLfloat)v.y, (GLfloat)v.z);

						v = vertex[t.v2];

						glVertex3f((GLfloat)v.x, (GLfloat)v.y, (GLfloat)v.z);

						v = vertex[t.v3];

						glVertex3f((GLfloat)v.x, (GLfloat)v.y, (GLfloat)v.z);

						glEnd();
					}
					// ------------------
				}
				else
				{
					// draw the triangles
					for (Size index = 0; index < triangle.size(); ++index)
					{
						glBegin(GL_TRIANGLES);

						t = triangle[index];

						v = vertex[t.v1];
						n = normal[t.v1];

						glNormal3f((GLfloat)n.x, (GLfloat)n.y, (GLfloat)n.z);
						glVertex3f((GLfloat)v.x, (GLfloat)v.y, (GLfloat)v.z);

						v = vertex[t.v2];
						n = normal[t.v2];

						glNormal3f((GLfloat)n.x, (GLfloat)n.y, (GLfloat)n.z);
						glVertex3f((GLfloat)v.x, (GLfloat)v.y, (GLfloat)v.z);

						v = vertex[t.v3];
						n = normal[t.v3];

						glNormal3f((GLfloat)n.x, (GLfloat)n.y, (GLfloat)n.z);
						glVertex3f((GLfloat)v.x, (GLfloat)v.y, (GLfloat)v.z);

						glEnd();
					}
					// ------------------
				}
			}
			else // we have a different color for each vertex
			{
				unsigned int precision;
				unsigned int mode;

				getDrawingModeAndPrecision(mode, precision);

				Triangle t;
				Vector3 v, n;

				if (mode == GeometricObject::PROPERTY__DRAWING_MODE_DOTS)
				{
					glBegin(GL_POINTS);

					// draw the triangles with lines
					for (Size index = 0; index < triangle.size(); ++index)
					{
						t = triangle[index];

						v = vertex[t.v1];
						// set the color
						ColorRGBA col = colorList[t.v1];
						glColor4ub((unsigned char)col.getRed(),
	 						 				 (unsigned char)col.getGreen(),
											 (unsigned char)col.getBlue(),
											 (unsigned char)col.getAlpha());

						glVertex3f((GLfloat)v.x, (GLfloat)v.y, (GLfloat)v.z);
					}

					glEnd();
					// ------------------
				}
				else if (mode == GeometricObject::PROPERTY__DRAWING_MODE_WIREFRAME)
				{
					// draw the triangles with lines
					for (Size index = 0; index < triangle.size(); ++index)
					{
						glBegin(GL_LINE_STRIP);

						t = triangle[index];

						v = vertex[t.v1];

						ColorRGBA col = colorList[t.v1];
						glColor4ub((unsigned char)col.getRed(),
	 						 				 (unsigned char)col.getGreen(),
											 (unsigned char)col.getBlue(),
											 (unsigned char)col.getAlpha());

						glVertex3f((GLfloat)v.x, (GLfloat)v.y, (GLfloat)v.z);

						v = vertex[t.v2];

						col = colorList[t.v2];
						glColor4ub((unsigned char)col.getRed(),
	 						 				 (unsigned char)col.getGreen(),
											 (unsigned char)col.getBlue(),
											 (unsigned char)col.getAlpha());

						glVertex3f((GLfloat)v.x, (GLfloat)v.y, (GLfloat)v.z);

						v = vertex[t.v3];

						col = colorList[t.v3];
						glColor4ub((unsigned char)col.getRed(),
	 						 				 (unsigned char)col.getGreen(),
											 (unsigned char)col.getBlue(),
											 (unsigned char)col.getAlpha());

						glVertex3f((GLfloat)v.x, (GLfloat)v.y, (GLfloat)v.z);

						glEnd();
					}
					// ------------------
				}
				else
				{
					// draw the triangles
					for (Size index = 0; index < triangle.size(); ++index)
					{
						glBegin(GL_TRIANGLES);

						t = triangle[index];

						v = vertex[t.v1];
						n = normal[t.v1];
						ColorRGBA col = colorList[t.v1];
						glColor4ub((unsigned char)col.getRed(),
	 						 				 (unsigned char)col.getGreen(),
											 (unsigned char)col.getBlue(),
											 (unsigned char)col.getAlpha());

						glNormal3f((GLfloat)n.x, (GLfloat)n.y, (GLfloat)n.z);
						glVertex3f((GLfloat)v.x, (GLfloat)v.y, (GLfloat)v.z);

						v = vertex[t.v2];
						n = normal[t.v2];
						col = colorList[t.v2];
						glColor4ub((unsigned char)col.getRed(),
	 						 				 (unsigned char)col.getGreen(),
											 (unsigned char)col.getBlue(),
											 (unsigned char)col.getAlpha());

						glNormal3f((GLfloat)n.x, (GLfloat)n.y, (GLfloat)n.z);
						glVertex3f((GLfloat)v.x, (GLfloat)v.y, (GLfloat)v.z);

						v = vertex[t.v3];
						n = normal[t.v3];
						col = colorList[t.v3];
						glColor4ub((unsigned char)col.getRed(),
	 						 				 (unsigned char)col.getGreen(),
											 (unsigned char)col.getBlue(),
											 (unsigned char)col.getAlpha());

						glNormal3f((GLfloat)n.x, (GLfloat)n.y, (GLfloat)n.z);
						glVertex3f((GLfloat)v.x, (GLfloat)v.y, (GLfloat)v.z);

						glEnd();
					}
					// ------------------
				}
			}
			glPopMatrix();

			return true;
		}

		bool GLMesh::extract()
			throw()
		{
			return Mesh::extract();
		}

	} // namespace VIEW

} // namespace BALL
<|endoftext|>


<commit_before>#include <memory>

#include "gtest/gtest.h"
#include "win32/library.hpp"
#include "common/version.hpp"

#include "xfsapi.h"

static Windows::Library *lib = nullptr;

TEST(MgrLoader, LibIsLoaded)
{
  EXPECT_NE(lib,nullptr);
}

TEST(MgrLoader, BadVersionRange)
{
  XFS::VersionRange vr(XFS::Version(3,20),XFS::Version(3,0));
  WFSVERSION xfsV;

  EXPECT_EQ(
    lib->call< HRESULT >(
      "WFSStartUp",
      vr.value(),
      &xfsV),
    WFS_ERR_INTERNAL_ERROR);
}

TEST(MgrLoader, VersionTooHigh)
{
  XFS::VersionRange vr(XFS::Version(3,30),XFS::Version(3,40));
  WFSVERSION xfsV;

  EXPECT_EQ(
    lib->call< HRESULT >(
      "WFSStartUp",
      vr.value(),
      &xfsV),
    WFS_ERR_API_VER_TOO_HIGH);
}

TEST(MgrLoader, VersionTooLow)
{
  XFS::VersionRange vr(XFS::Version(3,0),XFS::Version(3,10));
  WFSVERSION xfsV;

  EXPECT_EQ(
    lib->call< HRESULT >(
      "WFSStartUp",
      vr.value(),
      &xfsV),
    WFS_ERR_API_VER_TOO_LOW);
}

TEST(MgrLoader, InvalidPointer)
{
  XFS::VersionRange vr(XFS::Version(3,20),XFS::Version(3,20));

  EXPECT_EQ(
    lib->call< HRESULT >(
      "WFSStartUp",
      vr.value(),
      NULL),
    WFS_ERR_INVALID_POINTER);
}

TEST(MgrLoader, PlainCall)
{
  XFS::VersionRange vr(XFS::Version(3,0),XFS::Version(3,20));
  WFSVERSION xfsV;

  EXPECT_EQ(
    lib->call< HRESULT >(
      "WFSStartUp",
      vr.value(),
      &xfsV),
    WFS_SUCCESS);
}

TEST(MgrLoader, AlreadyStarted)
{
  XFS::VersionRange vr(XFS::Version(3,20),XFS::Version(3,20));
  WFSVERSION xfsV;

  EXPECT_EQ(
    lib->call< HRESULT >(
      "WFSStartUp",
      vr.value(),
      &xfsV),
    WFS_ERR_ALREADY_STARTED);
}

int wmain(int argc, wchar_t **argv, wchar_t **envp)
{
  Windows::Library l{ std::wstring(argv[1]) };
  lib = &l;

  ::testing::InitGoogleTest(&argc,argv);

  return RUN_ALL_TESTS();
}
<commit_msg>Fixed build errors<commit_after>#include <memory>

#include "gtest/gtest.h"
#include "win32/library.hpp"
#include "common/version.hpp"

#include "xfsapi.h"

static Windows::Library *lib = nullptr;

TEST(MgrLoader, LibIsLoaded)
{
  EXPECT_NE(lib,nullptr);
}

TEST(MgrLoader, BadVersionRange)
{
  XFS::VersionRange vr(XFS::Version(3,20),XFS::Version(3,0));
  WFSVERSION xfsV;

  EXPECT_EQ(
    lib->call< HRESULT >(
      "WFSStartUp",
      vr.value(),
      &xfsV),
    WFS_ERR_INTERNAL_ERROR);
}

TEST(MgrLoader, VersionTooHigh)
{
  XFS::VersionRange vr(XFS::Version(3,30),XFS::Version(3,40));
  WFSVERSION xfsV;

  EXPECT_EQ(
    lib->call< HRESULT >(
      "WFSStartUp",
      vr.value(),
      &xfsV),
    WFS_ERR_API_VER_TOO_HIGH);
}

TEST(MgrLoader, VersionTooLow)
{
  XFS::VersionRange vr(XFS::Version(3,0),XFS::Version(3,10));
  WFSVERSION xfsV;

  EXPECT_EQ(
    lib->call< HRESULT >(
      "WFSStartUp",
      vr.value(),
      &xfsV),
    WFS_ERR_API_VER_TOO_LOW);
}

TEST(MgrLoader, InvalidPointer)
{
  XFS::VersionRange vr(XFS::Version(3,20),XFS::Version(3,20));

  EXPECT_EQ(
    lib->call< HRESULT >(
      "WFSStartUp",
      vr.value(),
      NULL),
    WFS_ERR_INVALID_POINTER);
}

TEST(MgrLoader, PlainCall)
{
  XFS::VersionRange vr(XFS::Version(3,0),XFS::Version(3,20));
  WFSVERSION xfsV;

  EXPECT_EQ(
    lib->call< HRESULT >(
      "WFSStartUp",
      vr.value(),
      &xfsV),
    WFS_SUCCESS);
}

TEST(MgrLoader, AlreadyStarted)
{
  XFS::VersionRange vr(XFS::Version(3,20),XFS::Version(3,20));
  WFSVERSION xfsV;

  EXPECT_EQ(
    lib->call< HRESULT >(
      "WFSStartUp",
      vr.value(),
      &xfsV),
    WFS_ERR_ALREADY_STARTED);
}

int wmain(int argc, wchar_t **argv, wchar_t **envp)
{
  Windows::Library l((std::wstring(argv[1])));
  lib = &l;

  ::testing::InitGoogleTest(&argc,argv);

  return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>#include "terminal.hh"

#include <sys/ioctl.h>
#include <unistd.h>

#include <sstream>
#include <string>

namespace terminal {

namespace {
int g_cached_columns = -1;
WantColor g_want_color = WantColor::AUTO;
}  // namespace

void Init(WantColor want) {
  if (want == WantColor::AUTO) {
    g_want_color = isatty(STDOUT_FILENO) == 1 ? WantColor::YES : WantColor::NO;
  } else {
    g_want_color = want;
  }
}

int Columns() {
  int c;
  struct winsize ws {};

  if (g_cached_columns >= 0) {
    return g_cached_columns;
  }

  if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0 && ws.ws_col > 0) {
    c = ws.ws_col;
  } else {
    c = isatty(STDOUT_FILENO) == 1 ? 80 : 0;
  }

  g_cached_columns = c;
  return g_cached_columns;
}

#define DEFINE_COLOR(ColorName, ColorCode)       \
  std::string ColorName(const std::string& s) {  \
    if (g_want_color == WantColor::NO) return s; \
    std::stringstream ss;                        \
    ss << (ColorCode) << s << "\033[0m";         \
    return ss.str();                             \
  }

DEFINE_COLOR(Bold, "\033[1m");
DEFINE_COLOR(BoldRed, "\033[1;31m");
DEFINE_COLOR(BoldGreen, "\033[1;32m");
DEFINE_COLOR(BoldMagenta, "\033[1;35m");
DEFINE_COLOR(BoldCyan, "\033[1;36m");

#undef DEFINE_COLOR

}  // namespace terminal
<commit_msg>More code behind fewer macros<commit_after>#include "terminal.hh"

#include <sys/ioctl.h>
#include <unistd.h>

#include <sstream>
#include <string>

namespace terminal {

namespace {
int g_cached_columns = -1;
WantColor g_want_color = WantColor::AUTO;

std::string Color(const std::string& s, const char* color) {
  if (g_want_color == WantColor::NO) {
    return s;
  }

  std::stringstream ss;
  ss << color << s << "\033[0m";
  return ss.str();
}

}  // namespace

std::string Bold(const std::string& s) { return Color(s, "\033[1m"); }
std::string BoldRed(const std::string& s) { return Color(s, "\033[1;31m"); }
std::string BoldCyan(const std::string& s) { return Color(s, "\033[1;36m"); }
std::string BoldGreen(const std::string& s) { return Color(s, "\033[1;32m"); }
std::string BoldMagenta(const std::string& s) { return Color(s, "\033[1;35m"); }

void Init(WantColor want) {
  if (want == WantColor::AUTO) {
    g_want_color = isatty(STDOUT_FILENO) == 1 ? WantColor::YES : WantColor::NO;
  } else {
    g_want_color = want;
  }
}

int Columns() {
  int c;
  struct winsize ws {};

  if (g_cached_columns >= 0) {
    return g_cached_columns;
  }

  if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0 && ws.ws_col > 0) {
    c = ws.ws_col;
  } else {
    c = isatty(STDOUT_FILENO) == 1 ? 80 : 0;
  }

  g_cached_columns = c;
  return g_cached_columns;
}

}  // namespace terminal
<|endoftext|>