<commit_before>#pragma once

#include <vector>
#include <algorithm>

// ----------------------------------------------------------------------

namespace acmacs
{
    template <typename T> class flat_set_t
    {
      public:
        flat_set_t() = default;
        flat_set_t(std::initializer_list<T> source) : data_(source) {}

        auto begin() const { return data_.begin(); }
        auto end() const { return data_.end(); }
        auto empty() const { return data_.empty(); }
        auto size() const { return data_.size(); }
        auto clear() { data_.clear(); }

        const auto& front() const { return data_.front(); }
        void sort() { std::sort(std::begin(data_), std::end(data_)); }

        template <typename Predicate> void erase_if(Predicate&& pred)
        {
            data_.erase(std::remove_if(std::begin(data_), std::end(data_), std::forward<Predicate>(pred)), std::end(data_));
        }

        void add(const T& elt)
        {
            if (std::find(std::begin(data_), std::end(data_), elt) == std::end(data_))
                data_.push_back(elt);
        }

        void add(T&& elt)
        {
            if (std::find(std::begin(data_), std::end(data_), elt) == std::end(data_))
                data_.push_back(std::move(elt));
        }

        void add_and_sort(const T& elt)
        {
            if (std::find(std::begin(data_), std::end(data_), elt) == std::end(data_)) {
                data_.push_back(elt);
                sort();
            }
        }

        void merge_from(const flat_set_t& source)
        {
            for (const auto& src : source)
                add(src);
        }

      private:
        std::vector<T> data_;
    };

} // namespace acmacs

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<commit_msg>flat_set improvement<commit_after>#pragma once

#include <vector>
#include <algorithm>

// ----------------------------------------------------------------------

namespace acmacs
{
    enum class flat_set_sort_afterwards { no, yes };

    template <typename T> class flat_set_t
    {
      public:
        flat_set_t() = default;
        flat_set_t(std::initializer_list<T> source) : data_(source) {}

        auto begin() const { return data_.begin(); }
        auto end() const { return data_.end(); }
        auto empty() const { return data_.empty(); }
        auto size() const { return data_.size(); }
        auto clear() { data_.clear(); }

        const auto& front() const { return data_.front(); }
        void sort() { std::sort(std::begin(data_), std::end(data_)); }

        template <typename Predicate> void erase_if(Predicate&& pred)
        {
            data_.erase(std::remove_if(std::begin(data_), std::end(data_), std::forward<Predicate>(pred)), std::end(data_));
        }

        void add(const T& elt, flat_set_sort_afterwards a_sort = flat_set_sort_afterwards::no)
        {
            if (std::find(std::begin(data_), std::end(data_), elt) == std::end(data_)) {
                data_.push_back(elt);
                if (a_sort == flat_set_sort_afterwards::yes)
                    sort();
            }
        }

        void add(T&& elt, flat_set_sort_afterwards a_sort = flat_set_sort_afterwards::no)
        {
            if (std::find(std::begin(data_), std::end(data_), elt) == std::end(data_)) {
                data_.push_back(std::move(elt));
                if (a_sort == flat_set_sort_afterwards::yes)
                    sort();
            }
        }

        void merge_from(const flat_set_t& source, flat_set_sort_afterwards a_sort = flat_set_sort_afterwards::no)
        {
            for (const auto& src : source)
                add(src, flat_set_sort_afterwards::no);
            if (a_sort == flat_set_sort_afterwards::yes)
                sort();
        }

      private:
        std::vector<T> data_;
    };

} // namespace acmacs

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<|endoftext|>


<commit_before>#include <algorithm>
#include <array>
#include <iostream>
#include <string>

#include "gtest/gtest.h"

#include "sparse-array.h"

namespace cs375 {

// Test with nastier types to additionally test memory correctness.
class SparseArrayTest : public ::testing::Test {
    protected:
    sparse_array<std::string> array{17};
};

TEST_F(SparseArrayTest, StartsEmpty) {
    EXPECT_EQ(0, array.size());
}

TEST_F(SparseArrayTest, Contains_Nonexistent) {
    EXPECT_FALSE(array.contains(0));
}

TEST_F(SparseArrayTest, At_Nonexistent) {
    EXPECT_EQ(nullptr, array.at(0));
}

TEST_F(SparseArrayTest, Erase_Nonexistent) {
    EXPECT_FALSE(array.erase(0));
}

TEST_F(SparseArrayTest, Insert_Nonexistent) {
    auto result = array.emplace(0, "Hello");
    ASSERT_NE(nullptr, result);
    EXPECT_EQ("Hello", *result);
}

TEST_F(SparseArrayTest, Insert_Nonexistent_IncreasesSize) {
    array.emplace(0, "Hello");
    EXPECT_EQ(1, array.size());
}

TEST_F(SparseArrayTest, Contains_Existent) {
    array.emplace(0, "Hello");
    EXPECT_TRUE(array.contains(0));
}

TEST_F(SparseArrayTest, At_Existent) {
    auto expected = array.emplace(0, "Hello");
    EXPECT_EQ(expected, array.at(0));
}

TEST_F(SparseArrayTest, Erase_Existent) {
    array.emplace(0, "Hello");
    EXPECT_TRUE(array.erase(0));
}

TEST_F(SparseArrayTest, Erase_Existent_DecreasesSize) {
    array.emplace(0, "Hello");
    array.erase(0);
    EXPECT_EQ(0, array.size());
}

TEST_F(SparseArrayTest, Insert_Existent) {
    array.emplace(0, "Hello");
    EXPECT_EQ(nullptr, array.emplace(0, "Goodbye"));
}

TEST_F(SparseArrayTest, Insert_Twice) {
    array.emplace(1, "Hello");
    auto result = array.emplace(0, "Goodbye");
    ASSERT_NE(nullptr, result);
    EXPECT_EQ("Goodbye", *result);
}

TEST_F(SparseArrayTest, Erase_FirstInserted) {
    array.emplace(1, "Hello");
    array.emplace(0, "Goodbye");
    EXPECT_TRUE(array.erase(1));
}

TEST_F(SparseArrayTest, Erase_SecondInserted) {
    array.emplace(1, "Hello");
    array.emplace(0, "Goodbye");
    EXPECT_TRUE(array.erase(0));
}

TEST_F(SparseArrayTest, Iteration_Empty) {
    std::array<std::string, 0> expected;
    EXPECT_TRUE(std::is_permutation(array.begin(), array.end(), expected.begin()));
}

TEST_F(SparseArrayTest, Iteration_SizeOne) {
    array.emplace(0, "Hello");
    std::string expected[] = {"Hello"};
    EXPECT_TRUE(std::is_permutation(array.begin(), array.end(), expected));
}

TEST_F(SparseArrayTest, Iteration_SizeTwo) {
    array.emplace(1, "Hello");
    array.emplace(0, "Goodbye");
    std::string expected[] = {"Hello", "Goodbye"};
    EXPECT_TRUE(std::is_permutation(array.begin(), array.end(), expected));
}

TEST(SparseArrayDestructorTest, DoesDestroy) {
    bool destroyed = false;
    struct nontrivally_destroyable {
        bool &destroyed;
        ~nontrivally_destroyable() {
            destroyed = true;
        }
    };
    {
        sparse_array<nontrivally_destroyable> arr(17);
        arr.emplace(1, destroyed);
    }
    ASSERT_TRUE(destroyed);
}

}
<commit_msg>Make iteration tests more robust<commit_after>#include <algorithm>
#include <array>
#include <iostream>
#include <iterator>
#include <string>

#include "gtest/gtest.h"

#include "sparse-array.h"

namespace cs375 {

// Test with nastier types to additionally test memory correctness.
class SparseArrayTest : public ::testing::Test {
    protected:
    sparse_array<std::string> array{17};
};

TEST_F(SparseArrayTest, StartsEmpty) {
    EXPECT_EQ(0, array.size());
}

TEST_F(SparseArrayTest, Contains_Nonexistent) {
    EXPECT_FALSE(array.contains(0));
}

TEST_F(SparseArrayTest, At_Nonexistent) {
    EXPECT_EQ(nullptr, array.at(0));
}

TEST_F(SparseArrayTest, Erase_Nonexistent) {
    EXPECT_FALSE(array.erase(0));
}

TEST_F(SparseArrayTest, Insert_Nonexistent) {
    auto result = array.emplace(0, "Hello");
    ASSERT_NE(nullptr, result);
    EXPECT_EQ("Hello", *result);
}

TEST_F(SparseArrayTest, Insert_Nonexistent_IncreasesSize) {
    array.emplace(0, "Hello");
    EXPECT_EQ(1, array.size());
}

TEST_F(SparseArrayTest, Contains_Existent) {
    array.emplace(0, "Hello");
    EXPECT_TRUE(array.contains(0));
}

TEST_F(SparseArrayTest, At_Existent) {
    auto expected = array.emplace(0, "Hello");
    EXPECT_EQ(expected, array.at(0));
}

TEST_F(SparseArrayTest, Erase_Existent) {
    array.emplace(0, "Hello");
    EXPECT_TRUE(array.erase(0));
}

TEST_F(SparseArrayTest, Erase_Existent_DecreasesSize) {
    array.emplace(0, "Hello");
    array.erase(0);
    EXPECT_EQ(0, array.size());
}

TEST_F(SparseArrayTest, Insert_Existent) {
    array.emplace(0, "Hello");
    EXPECT_EQ(nullptr, array.emplace(0, "Goodbye"));
}

TEST_F(SparseArrayTest, Insert_Twice) {
    array.emplace(1, "Hello");
    auto result = array.emplace(0, "Goodbye");
    ASSERT_NE(nullptr, result);
    EXPECT_EQ("Goodbye", *result);
}

TEST_F(SparseArrayTest, Erase_FirstInserted) {
    array.emplace(1, "Hello");
    array.emplace(0, "Goodbye");
    EXPECT_TRUE(array.erase(1));
}

TEST_F(SparseArrayTest, Erase_SecondInserted) {
    array.emplace(1, "Hello");
    array.emplace(0, "Goodbye");
    EXPECT_TRUE(array.erase(0));
}

TEST_F(SparseArrayTest, Iteration_Empty) {
    EXPECT_EQ(array.end(), array.begin());
}

TEST_F(SparseArrayTest, Iteration_SizeOne) {
    array.emplace(0, "Hello");

    ASSERT_EQ(1, std::distance(array.begin(), array.end()));
    std::string expected[] = {"Hello"};
    EXPECT_TRUE(std::is_permutation(std::begin(expected), std::end(expected), array.begin()));
}

TEST_F(SparseArrayTest, Iteration_SizeTwo) {
    array.emplace(1, "Hello");
    array.emplace(0, "Goodbye");

    ASSERT_EQ(2, std::distance(array.begin(), array.end()));
    std::string expected[] = {"Hello", "Goodbye"};
    EXPECT_TRUE(std::is_permutation(std::begin(expected), std::end(expected), array.begin()));
}

TEST(SparseArrayDestructorTest, DoesDestroy) {
    bool destroyed = false;
    struct nontrivally_destroyable {
        bool &destroyed;
        ~nontrivally_destroyable() {
            destroyed = true;
        }
    };
    {
        sparse_array<nontrivally_destroyable> arr(17);
        arr.emplace(1, destroyed);
    }
    ASSERT_TRUE(destroyed);
}

}
<|endoftext|>


<commit_before>/*
This file is part of cpp-ethereum.

cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file whisperMessage.cpp
* @author Vladislav Gluhovsky <vlad@ethdev.com>
* @date July 2015
*/

#include <thread>
#include <boost/test/unit_test.hpp>
#include <libwhisper/WhisperDB.h>

using namespace std;
using namespace dev;
using namespace dev::shh;

BOOST_AUTO_TEST_SUITE(whisperDB)

BOOST_AUTO_TEST_CASE(basic)
{
	VerbosityHolder setTemporaryLevel(10);
	cnote << "Testing Whisper DB...";

	string s;
	string const text1 = "lorem";
	string const text2 = "ipsum";
	h256 h1(0xBEEF);
	h256 h2(0xC0FFEE);
	WhisperDB db;

	db.kill(h1);
	db.kill(h2);

	s = db.lookup(h1);
	BOOST_REQUIRE(s.empty());

	db.insert(h1, text2);
	s = db.lookup(h2);
	BOOST_REQUIRE(s.empty());
	s = db.lookup(h1);
	BOOST_REQUIRE(!s.compare(text2));

	db.insert(h1, text1);
	s = db.lookup(h2);
	BOOST_REQUIRE(s.empty());
	s = db.lookup(h1);
	BOOST_REQUIRE(!s.compare(text1));

	db.insert(h2, text2);
	s = db.lookup(h2);
	BOOST_REQUIRE(!s.compare(text2));
	s = db.lookup(h1);
	BOOST_REQUIRE(!s.compare(text1));

	db.kill(h1);
	db.kill(h2);

	s = db.lookup(h2);
	BOOST_REQUIRE(s.empty());
	s = db.lookup(h1);
	BOOST_REQUIRE(s.empty());
}

BOOST_AUTO_TEST_CASE(persistence)
{
	VerbosityHolder setTemporaryLevel(10);
	cnote << "Testing persistence of Whisper DB...";

	string s;
	string const text1 = "sator";
	string const text2 = "arepo";
	h256 const h1(0x12345678);
	h256 const h2(0xBADD00DE);

	{
		WhisperDB db;
		db.kill(h1);
		db.kill(h2);
		s = db.lookup(h1);
		BOOST_REQUIRE(s.empty());
		db.insert(h1, text2);
		s = db.lookup(h2);
		BOOST_REQUIRE(s.empty());
		s = db.lookup(h1);
		BOOST_REQUIRE(!s.compare(text2));
	}

	this_thread::sleep_for(chrono::milliseconds(20));

	{
		WhisperDB db;
		db.insert(h1, text1);
		db.insert(h2, text2);
	}

	this_thread::sleep_for(chrono::milliseconds(20));

	{
		WhisperDB db;
		s = db.lookup(h2);
		BOOST_REQUIRE(!s.compare(text2));
		s = db.lookup(h1);
		BOOST_REQUIRE(!s.compare(text1));
		db.kill(h1);
		db.kill(h2);
	}
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>test added<commit_after>/*
This file is part of cpp-ethereum.

cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file whisperMessage.cpp
* @author Vladislav Gluhovsky <vlad@ethdev.com>
* @date July 2015
*/

#include <thread>
#include <boost/test/unit_test.hpp>
#include <libp2p/Host.h>
#include <libwhisper/WhisperDB.h>
#include <libwhisper/WhisperHost.h>

using namespace std;
using namespace dev;
using namespace dev::shh;

BOOST_AUTO_TEST_SUITE(whisperDB)

BOOST_AUTO_TEST_CASE(basic)
{
	VerbosityHolder setTemporaryLevel(10);
	cnote << "Testing Whisper DB...";

	string s;
	string const text1 = "lorem";
	string const text2 = "ipsum";
	h256 h1(0xBEEF);
	h256 h2(0xC0FFEE);
	WhisperDB db;

	db.kill(h1);
	db.kill(h2);

	s = db.lookup(h1);
	BOOST_REQUIRE(s.empty());

	db.insert(h1, text2);
	s = db.lookup(h2);
	BOOST_REQUIRE(s.empty());
	s = db.lookup(h1);
	BOOST_REQUIRE(!s.compare(text2));

	db.insert(h1, text1);
	s = db.lookup(h2);
	BOOST_REQUIRE(s.empty());
	s = db.lookup(h1);
	BOOST_REQUIRE(!s.compare(text1));

	db.insert(h2, text2);
	s = db.lookup(h2);
	BOOST_REQUIRE(!s.compare(text2));
	s = db.lookup(h1);
	BOOST_REQUIRE(!s.compare(text1));

	db.kill(h1);
	db.kill(h2);

	s = db.lookup(h2);
	BOOST_REQUIRE(s.empty());
	s = db.lookup(h1);
	BOOST_REQUIRE(s.empty());
}

BOOST_AUTO_TEST_CASE(persistence)
{
	VerbosityHolder setTemporaryLevel(10);
	cnote << "Testing persistence of Whisper DB...";

	string s;
	string const text1 = "sator";
	string const text2 = "arepo";
	h256 const h1(0x12345678);
	h256 const h2(0xBADD00DE);

	{
		WhisperDB db;
		db.kill(h1);
		db.kill(h2);
		s = db.lookup(h1);
		BOOST_REQUIRE(s.empty());
		db.insert(h1, text2);
		s = db.lookup(h2);
		BOOST_REQUIRE(s.empty());
		s = db.lookup(h1);
		BOOST_REQUIRE(!s.compare(text2));
	}

	this_thread::sleep_for(chrono::milliseconds(20));

	{
		WhisperDB db;
		db.insert(h1, text1);
		db.insert(h2, text2);
	}

	this_thread::sleep_for(chrono::milliseconds(20));

	{
		WhisperDB db;
		s = db.lookup(h2);
		BOOST_REQUIRE(!s.compare(text2));
		s = db.lookup(h1);
		BOOST_REQUIRE(!s.compare(text1));
		db.kill(h1);
		db.kill(h2);
	}
}

BOOST_AUTO_TEST_CASE(messages)
{
	cnote << "Testing load/save Whisper messages...";
	const unsigned TestSize = 3;
	map<h256, Envelope> m1;
	map<h256, Envelope> preexisting;
	KeyPair us = KeyPair::create();

	{
		p2p::Host h("Test");
		auto wh = h.registerCapability(new WhisperHost());
		preexisting = wh->all();
		cnote << preexisting.size() << "preexisting messages in DB";

		for (int i = 0; i < TestSize; ++i)
			wh->post(us.sec(), RLPStream().append(i).out(), BuildTopic("test"), 0xFFFFF);

		m1 = wh->all();
	}

	{
		p2p::Host h("Test");
		auto wh = h.registerCapability(new WhisperHost());
		map<h256, Envelope> m2 = wh->all();
		BOOST_REQUIRE_EQUAL(m1.size(), m2.size());
		BOOST_REQUIRE_EQUAL(m1.size() - preexisting.size(), TestSize);

		for (auto i: m1)
		{
			RLPStream rlp1;
			RLPStream rlp2;
			i.second.streamRLP(rlp1);
			m2[i.first].streamRLP(rlp2);
			BOOST_REQUIRE_EQUAL(rlp1.out().size(), rlp2.out().size());
			for (unsigned j = 0; j < rlp1.out().size(); ++j)
				BOOST_REQUIRE_EQUAL(rlp1.out()[j], rlp2.out()[j]);
		}
	}

	WhisperDB db;
	unsigned x = 0;

	for (auto i: m1)
		if (preexisting.find(i.first) == preexisting.end())
		{
			db.kill(i.first);
			++x;
		}

	BOOST_REQUIRE_EQUAL(x, TestSize);
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>/*	____________________________________________________________________________

	    Semantics and Coding Component Implementation for the Micro Compiler

	                               mcode.cpp

	                              Version 2007

	                           James L. Richards
	                     Last Update: August 28, 2007
	                     Update by M. J. Wolf: January 21,2016

	The routines in this unit are based on those provided in the book
	"Crafting A Compiler" by Charles N. Fischer and Richard J. LeBlanc, Jr.,
	Benjamin Cummings Publishing Co. (1991).

	See Section 2.3-2.4, pp. 31-40.
	____________________________________________________________________________
*/

#include <iostream>
#include <fstream>
using namespace std;

extern ifstream sourceFile;
extern ofstream outFile, listFile;

#include "mscan.h"   // Scanner class definition
#include "mcode.h"   // CodeGen class definition

extern Scanner scan; // global Scanner object declared in micro.cpp

// *******************
// **  Constructor  **
// *******************

CodeGen::CodeGen() {
	maxTemp = 0;
}

// *******************************
// ** Private Member Functions  **
// *******************************

void CodeGen::CheckId(ExprRec& var) {
	if (!LookUp(var.name)) { // variable not declared yet
		/* FIXME: check variable type */
		Enter(var);
	}
}

void CodeGen::Enter(ExprRec& var) {
	/* Create the key and fill it */
	symbol_node_t variable;
	variable.name = var.name;
	variable.type = var.var_type;
	/* Check variable size */
	switch (var.var_type) {
	case BOOL:
		variable.size = 1; /* 1x8 = 8bits */
		break;
	case INT:
		variable.size = 2; /* 2x8 = 16 bits */
		break;
	case FLOAT:
		variable.size = 4; /* 4x8 = 32 bits */
		break;
	default:
		/* TODO: check what to do. Check for cheese? */
		break;
	}
	/* Add the record to the symbol table */
	symbolTable.push_back(variable);
}

void CodeGen::ExtractExpr(const ExprRec & e, string& s) {
	string t;
	int k, n;

	/* TODO: check variable type */
	switch (e.kind) {
	case ID_EXPR:
	case TEMP_EXPR:  // operand form: +k(R15)
		s = e.name;
		k = n = 0;
		while (symbolTable[n].name != s) {
			n++;
			k += symbolTable[n].size;
		}
		/* FIXME: check what to do for other types */
		IntToAlpha(k, t);
		s = "+" + t + "(R15)";
		break;
	case LITERAL_EXPR:
		IntToAlpha(e.ival, t);
		s = "#" + t;
	}
}

string CodeGen::ExtractOp(const OpRec & o) {
	if (o.op == PLUS) {
		return "IA        ";
	} else if (o.op == MINUS) {
		return "IS        ";
	} else if (o.op == MULT) {
		return "IM        ";
	} else {
		return "ID        ";
	}
}
/* TODO: please check this for float + - / *    */
string CodeGen::ExtractOpFloat(const OpRec & o) {
	if (o.op == PLUS) {
		return "FADD        ";
	} else if (o.op == MINUS) {
		return "FSUB        ";
	} else if (o.op == MULT) {
		return "FMUL        ";
	} else {
		return "FDIV        ";
	}
}

void CodeGen::Generate(const string & s1, const string & s2, const string & s3) {
	listFile.width(20);
	listFile << ' ' << s1;
	outFile << s1;
	if (s2.length() > 0) {
		listFile << s2;
		outFile << s2;
		if (s3.length() > 0) {
			listFile << ',' << s3;
			outFile << ',' << s3;
		}
	}
	listFile << endl;
	outFile << endl;
}

string CodeGen::GetTemp() {
	/* FIXME: check what to do for other types */
	string s;
	static string t;

	t = "Temp&";
	IntToAlpha(++maxTemp, s);
	t += s;
	ExprRec var;
	var.name = t;
	var.var_type = INT;
	CheckId(var);
	return t;
}

void CodeGen::IntToAlpha(int val, string& str) {
	int k;
	char temp;

	str = "";
	if (val == 0) str = "0";
	while (val > 0) {
		str.append(1, (char)(val % 10 + (int)'0'));
		val /= 10;
	}
	k = int(str.length());
	for (int i = 0; i < k/2; i++) {
		temp = str[i];
		str[i] = str[k-i-1];
		str[k-i-1] = temp;
	}
}

bool CodeGen::LookUp(const string & s) {
	for (unsigned i = 0; i < symbolTable.size(); i++)
	if (symbolTable[i].name == s) {
		return true;
	}
	return false;
}

// ******************************
// ** Public Member Functions  **
// ******************************

void CodeGen::Assign(const ExprRec & target, const ExprRec & source) {
	/* TODO check variable types, add other types */
	string s;
	ExtractExpr(source, s);
	Generate("LD        ", "R0", s);
	ExtractExpr(target, s);
	Generate("STO       ", "R0", s);
}

vector<string> str_vect;
int str_cnt = 0;

int CodeGen::CalcTableSize() {
	int i, index = 0;
	for (i = 0; i < symbolTable.size(); i++) {
		index += symbolTable[i].size;
	}
	return index;
}

void CodeGen::Finish() {
	string s;

	listFile.width(6);
	listFile << ++scan.lineNumber << "  " << scan.lineBuffer << endl;
	Generate("HALT      ", "", "");
	Generate("LABEL     ", "VARS", "");
	int table_size = CalcTableSize();
	IntToAlpha(table_size, s);
	Generate("SKIP      ", s, "");
	Generate("LABEL     ", "STRS", "");
	while (!str_vect.empty()) {
		s = str_vect.front();
		str_vect.erase(str_vect.begin());
		Generate("STRING    ", s, "");
	}
	outFile.close();
	listFile << endl << endl;
	listFile << " _____________________________________________\n";
	listFile << " <><><><>   S Y M B O L   T A B L E   <><><><>\n"
		<< endl;
	listFile << " Relative" << endl;
	listFile << " Address      Identifier" << endl;
	listFile << " --------     --------------------------------"
		<< endl;
	int i, index = 0;
	for (i = 0; i < symbolTable.size(); i++) {
		listFile.width(7);
		listFile << index << "       " << symbolTable[i].name
			<< endl;
		index += symbolTable[i].size;
	}
	listFile << " _____________________________________________"
		<< endl;
	listFile << endl;
	listFile << " Normal successful compilation." << endl;
	listFile.close();
}

void CodeGen::GenInfix(const ExprRec & e1, const OpRec & op, const ExprRec & e2, ExprRec& e) {
	string opnd;
	/* TODO: check variable type -- should var_type be used for literals? */
	if (e1.kind == LITERAL_EXPR && e2.kind == LITERAL_EXPR) {
		e.kind = LITERAL_EXPR;
		switch (op.op) {
		case PLUS:
			e.ival = e1.ival + e2.ival;
			break;
		case MINUS:
			e.ival = e1.ival - e2.ival;
			break;
		case MULT:
			e.ival = e1.ival * e2.ival;
			break;
		case DIV:
			e.ival = e1.ival / e2.ival;
			break;
		}
	} else {
		e.kind = TEMP_EXPR;
		e.name = GetTemp();
		ExtractExpr(e1, opnd);
		Generate("LD        ", "R0", opnd);
		ExtractExpr(e2, opnd);
		Generate(ExtractOp(op), "R0", opnd);
		ExtractExpr(e, opnd);
		Generate("STO       ", "R0", opnd);
	}
}

void CodeGen::NewLine() {
	Generate("WRNL      ", "", "");
}

void CodeGen::ProcessVar(ExprRec& e)
{
	if (!LookUp(e.name)) { /* variable not declared yet */
		SemanticError("Variable " + e.name + \
				" was not declared before usage.");
	} else {
		e.kind = ID_EXPR;
		e.var_type = INT; /* FIXME: this should be retrieve from the symbol table in the codegen */
	}
}

void CodeGen::ProcessLit(ExprRec& e) {
	e.kind = LITERAL_EXPR;
	switch (e.var_type) {
	case BOOL:
		/* TODO: check if this works */
		e.bval = (scan.tokenBuffer == "True");
		break;
	case INT:
		e.ival = atoi(scan.tokenBuffer.data());
		break;
		case FLOAT:
		/* TODO: check size of float, is it float or double?  it is double :) */
		e.fval = atof(scan.tokenBuffer.data());
		break;
	case CHEESE:
		e.sval = scan.tokenBuffer;
		break;
	}
}

void CodeGen::ProcessOp(OpRec& o) {
	string c = scan.tokenBuffer;
	if (c == "+") {
		o.op = PLUS;
	} else if (c == "-") {
		o.op = MINUS;
	} else if (c == "*") {
		o.op = MULT;
	} else {
		o.op = DIV;
	}
}

void CodeGen::Listen(const ExprRec & inVar) {
	/* TODO check variable types, add other types */
	string s;
	ExtractExpr(inVar, s);
	Generate("RDI       ", s, "");
}

void CodeGen::Start() {
	Generate("LDA       ", "R15", "VARS");
	Generate("LDA       ", "R14", "STRS");
}

void CodeGen::Shout(const ExprRec & outExpr) {
	switch (outExpr.var_type) {
		case CHEESE:
			WriteString(outExpr);
			break;
		default:
			WriteExpr(outExpr);
			break;
	}
}

void CodeGen::WriteExpr(const ExprRec & outExpr) {
	string s;
	switch (outExpr.var_type) {
		case BOOL:
			/*TODO: please check this statement and check if it is
			 * right how I am vverifying if it is true or false */
			//ExtractExpr(outExpr, s);
			cerr << outExpr.bval << endl;
			if(outExpr.bval){
				Generate("WRI       ", "bl", "1");
			}else{
				Generate("WRI       ", "bl", "0");
			}
			break;
		case INT:
			ExtractExpr(outExpr, s);
			Generate("WRI       ", s, "");
			break;
		case FLOAT:
			/*TODO*/
			break;
		default:
			/*TODO*/ //error as there will always be one of the above.
			//otherwise we will have the warning after compiling that cheese wasnt handle(but it is in previous function)
			break;
	}
}

void CodeGen::WriteString(const ExprRec & outExpr) {
	string s, t;
	/* Save the string */
	s = outExpr.sval;
	str_vect.push_back(s);
	/* Update counter and Generate ASM */
	IntToAlpha(str_cnt, t);
	str_cnt += scan.cheese_size;
	if (str_cnt % 2) {
		str_cnt++;
	}
	s = "+" + t + "(R14)";
	Generate("WRST       ", s, "");
}

void CodeGen::DefineVar(ExprRec& var) {
	/* TODO Start checking variable type */
	string varname = scan.tokenBuffer;
	if (LookUp(varname)) {
		/* FIXME is this a semantic error? */
		SemanticError("Variable " + varname + \
				" was already declared before.");
	} else { /* variable not declared yet */
		var.name = varname;
		Enter(var); /* declare it */
		/* TODO Assign 0 to the variable, check if SAM does. */
	}
}

void CodeGen::SemanticError(string msg) { /* FIXME should this be here? */
	cout << "Semantic Error: " + msg << endl;
	exit(1); // abort on any semantic error
}
<commit_msg>Errors for mixed mode or wrong type arith. operation.<commit_after>/*	____________________________________________________________________________

	    Semantics and Coding Component Implementation for the Micro Compiler

	                               mcode.cpp

	                              Version 2007

	                           James L. Richards
	                     Last Update: August 28, 2007
	                     Update by M. J. Wolf: January 21,2016

	The routines in this unit are based on those provided in the book
	"Crafting A Compiler" by Charles N. Fischer and Richard J. LeBlanc, Jr.,
	Benjamin Cummings Publishing Co. (1991).

	See Section 2.3-2.4, pp. 31-40.
	____________________________________________________________________________
*/

#include <iostream>
#include <fstream>
using namespace std;

extern ifstream sourceFile;
extern ofstream outFile, listFile;

#include "mscan.h"   // Scanner class definition
#include "mcode.h"   // CodeGen class definition

extern Scanner scan; // global Scanner object declared in micro.cpp

// *******************
// **  Constructor  **
// *******************

CodeGen::CodeGen() {
	maxTemp = 0;
}

// *******************************
// ** Private Member Functions  **
// *******************************

void CodeGen::CheckId(ExprRec& var) {
	if (!LookUp(var.name)) { // variable not declared yet
		/* FIXME: check variable type */
		Enter(var);
	}
}

void CodeGen::Enter(ExprRec& var) {
	/* Create the key and fill it */
	symbol_node_t variable;
	variable.name = var.name;
	variable.type = var.var_type;
	/* Check variable size */
	switch (var.var_type) {
	case BOOL:
		variable.size = 1; /* 1x8 = 8bits */
		break;
	case INT:
		variable.size = 2; /* 2x8 = 16 bits */
		break;
	case FLOAT:
		variable.size = 4; /* 4x8 = 32 bits */
		break;
	default:
		/* TODO: check what to do. Check for cheese? */
		break;
	}
	/* Add the record to the symbol table */
	symbolTable.push_back(variable);
}

void CodeGen::ExtractExpr(const ExprRec & e, string& s) {
	string t;
	int k, n;

	/* TODO: check variable type */
	switch (e.kind) {
	case ID_EXPR:
	case TEMP_EXPR:  // operand form: +k(R15)
		s = e.name;
		k = n = 0;
		while (symbolTable[n].name != s) {
			n++;
			k += symbolTable[n].size;
		}
		/* FIXME: check what to do for other types */
		IntToAlpha(k, t);
		s = "+" + t + "(R15)";
		break;
	case LITERAL_EXPR:
		IntToAlpha(e.ival, t);
		s = "#" + t;
	}
}

string CodeGen::ExtractOp(const OpRec & o) {
	if (o.op == PLUS) {
		return "IA        ";
	} else if (o.op == MINUS) {
		return "IS        ";
	} else if (o.op == MULT) {
		return "IM        ";
	} else {
		return "ID        ";
	}
}
/* TODO: please check this for float + - / *    */
string CodeGen::ExtractOpFloat(const OpRec & o) {
	if (o.op == PLUS) {
		return "FADD        ";
	} else if (o.op == MINUS) {
		return "FSUB        ";
	} else if (o.op == MULT) {
		return "FMUL        ";
	} else {
		return "FDIV        ";
	}
}

void CodeGen::Generate(const string & s1, const string & s2, const string & s3) {
	listFile.width(20);
	listFile << ' ' << s1;
	outFile << s1;
	if (s2.length() > 0) {
		listFile << s2;
		outFile << s2;
		if (s3.length() > 0) {
			listFile << ',' << s3;
			outFile << ',' << s3;
		}
	}
	listFile << endl;
	outFile << endl;
}

string CodeGen::GetTemp() {
	/* FIXME: check what to do for other types */
	string s;
	static string t;

	t = "Temp&";
	IntToAlpha(++maxTemp, s);
	t += s;
	ExprRec var;
	var.name = t;
	var.var_type = INT;
	CheckId(var);
	return t;
}

void CodeGen::IntToAlpha(int val, string& str) {
	int k;
	char temp;

	str = "";
	if (val == 0) str = "0";
	while (val > 0) {
		str.append(1, (char)(val % 10 + (int)'0'));
		val /= 10;
	}
	k = int(str.length());
	for (int i = 0; i < k/2; i++) {
		temp = str[i];
		str[i] = str[k-i-1];
		str[k-i-1] = temp;
	}
}

bool CodeGen::LookUp(const string & s) {
	for (unsigned i = 0; i < symbolTable.size(); i++)
	if (symbolTable[i].name == s) {
		return true;
	}
	return false;
}

// ******************************
// ** Public Member Functions  **
// ******************************

void CodeGen::Assign(const ExprRec & target, const ExprRec & source) {
	/* TODO check variable types, add other types */
	string s;
	ExtractExpr(source, s);
	Generate("LD        ", "R0", s);
	ExtractExpr(target, s);
	Generate("STO       ", "R0", s);
}

vector<string> str_vect;
int str_cnt = 0;

int CodeGen::CalcTableSize() {
	int i, index = 0;
	for (i = 0; i < symbolTable.size(); i++) {
		index += symbolTable[i].size;
	}
	return index;
}

void CodeGen::Finish() {
	string s;

	listFile.width(6);
	listFile << ++scan.lineNumber << "  " << scan.lineBuffer << endl;
	Generate("HALT      ", "", "");
	Generate("LABEL     ", "VARS", "");
	int table_size = CalcTableSize();
	IntToAlpha(table_size, s);
	Generate("SKIP      ", s, "");
	Generate("LABEL     ", "STRS", "");
	while (!str_vect.empty()) {
		s = str_vect.front();
		str_vect.erase(str_vect.begin());
		Generate("STRING    ", s, "");
	}
	outFile.close();
	listFile << endl << endl;
	listFile << " _____________________________________________\n";
	listFile << " <><><><>   S Y M B O L   T A B L E   <><><><>\n"
		<< endl;
	listFile << " Relative" << endl;
	listFile << " Address      Identifier" << endl;
	listFile << " --------     --------------------------------"
		<< endl;
	int i, index = 0;
	for (i = 0; i < symbolTable.size(); i++) {
		listFile.width(7);
		listFile << index << "       " << symbolTable[i].name
			<< endl;
		index += symbolTable[i].size;
	}
	listFile << " _____________________________________________"
		<< endl;
	listFile << endl;
	listFile << " Normal successful compilation." << endl;
	listFile.close();
}

void CodeGen::GenInfix(const ExprRec & e1, const OpRec & op, const ExprRec & e2, ExprRec& e) {

	if (e1.var_type != e2.var_type) {
		SemanticError(" mixed-mode arithmetic operations"
				" are not allowed.");
	} else if ((e1.var_type != INT) && (e1.var_type != FLOAT)) {
		SemanticError(" arithmetic opertions are allowed only for"
				" INTs and FLOATs.");
	}

	if (e1.kind == LITERAL_EXPR && e2.kind == LITERAL_EXPR) {
		e.kind = LITERAL_EXPR;
		switch (op.op) {
		case PLUS:
			e.ival = e1.ival + e2.ival;
			break;
		case MINUS:
			e.ival = e1.ival - e2.ival;
			break;
		case MULT:
			e.ival = e1.ival * e2.ival;
			break;
		case DIV:
			e.ival = e1.ival / e2.ival;
			break;
		}
	} else {
		string opnd;
		/* TODO: check variable type */
		e.kind = TEMP_EXPR;
		e.name = GetTemp();
		ExtractExpr(e1, opnd);
		Generate("LD        ", "R0", opnd);
		ExtractExpr(e2, opnd);
		Generate(ExtractOp(op), "R0", opnd);
		ExtractExpr(e, opnd);
		Generate("STO       ", "R0", opnd);
	}
}

void CodeGen::NewLine() {
	Generate("WRNL      ", "", "");
}

void CodeGen::ProcessVar(ExprRec& e)
{
	if (!LookUp(e.name)) { /* variable not declared yet */
		SemanticError("Variable " + e.name + \
				" was not declared before usage.");
	} else {
		e.kind = ID_EXPR;
		e.var_type = INT; /* FIXME: this should be retrieve from the symbol table in the codegen */
	}
}

void CodeGen::ProcessLit(ExprRec& e) {
	e.kind = LITERAL_EXPR;
	switch (e.var_type) {
	case BOOL:
		/* TODO: check if this works */
		e.bval = (scan.tokenBuffer == "True");
		break;
	case INT:
		e.ival = atoi(scan.tokenBuffer.data());
		break;
		case FLOAT:
		/* TODO: check size of float, is it float or double?  it is double :) */
		e.fval = atof(scan.tokenBuffer.data());
		break;
	case CHEESE:
		e.sval = scan.tokenBuffer;
		break;
	}
}

void CodeGen::ProcessOp(OpRec& o) {
	string c = scan.tokenBuffer;
	if (c == "+") {
		o.op = PLUS;
	} else if (c == "-") {
		o.op = MINUS;
	} else if (c == "*") {
		o.op = MULT;
	} else {
		o.op = DIV;
	}
}

void CodeGen::Listen(const ExprRec & inVar) {
	/* TODO check variable types, add other types */
	string s;
	ExtractExpr(inVar, s);
	Generate("RDI       ", s, "");
}

void CodeGen::Start() {
	Generate("LDA       ", "R15", "VARS");
	Generate("LDA       ", "R14", "STRS");
}

void CodeGen::Shout(const ExprRec & outExpr) {
	switch (outExpr.var_type) {
		case CHEESE:
			WriteString(outExpr);
			break;
		default:
			WriteExpr(outExpr);
			break;
	}
}

void CodeGen::WriteExpr(const ExprRec & outExpr) {
	string s;
	switch (outExpr.var_type) {
		case BOOL:
			/*TODO: please check this statement and check if it is
			 * right how I am vverifying if it is true or false */
			//ExtractExpr(outExpr, s);
			cerr << outExpr.bval << endl;
			if(outExpr.bval){
				Generate("WRI       ", "bl", "1");
			}else{
				Generate("WRI       ", "bl", "0");
			}
			break;
		case INT:
			ExtractExpr(outExpr, s);
			Generate("WRI       ", s, "");
			break;
		case FLOAT:
			/*TODO*/
			break;
		default:
			/*TODO*/ //error as there will always be one of the above.
			//otherwise we will have the warning after compiling that cheese wasnt handle(but it is in previous function)
			break;
	}
}

void CodeGen::WriteString(const ExprRec & outExpr) {
	string s, t;
	/* Save the string */
	s = outExpr.sval;
	str_vect.push_back(s);
	/* Update counter and Generate ASM */
	IntToAlpha(str_cnt, t);
	str_cnt += scan.cheese_size;
	if (str_cnt % 2) {
		str_cnt++;
	}
	s = "+" + t + "(R14)";
	Generate("WRST       ", s, "");
}

void CodeGen::DefineVar(ExprRec& var) {
	/* TODO Start checking variable type */
	string varname = scan.tokenBuffer;
	if (LookUp(varname)) {
		/* FIXME is this a semantic error? */
		SemanticError("Variable " + varname + \
				" was already declared before.");
	} else { /* variable not declared yet */
		var.name = varname;
		Enter(var); /* declare it */
		/* TODO Assign 0 to the variable, check if SAM does. */
	}
}

void CodeGen::SemanticError(string msg) { /* FIXME should this be here? */
	cout << " *** Semantic Error: " + msg << endl;
	exit(1); // abort on any semantic error
}
<|endoftext|>


<commit_before>/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "GrInOrderDrawBuffer.h"

// We will use the reordering buffer, unless we have NVPR.
// TODO move NVPR to batch so we can reorder
static inline bool allow_reordering(const GrGpu* gpu) {
    const GrCaps* caps = gpu->caps();
    return caps && caps->shaderCaps() && !caps->shaderCaps()->pathRenderingSupport();
}

GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrContext* context)
    : INHERITED(context)
    , fCommands(GrCommandBuilder::Create(context->getGpu(), allow_reordering(context->getGpu())))
    , fPathIndexBuffer(kPathIdxBufferMinReserve * sizeof(char)/4)
    , fPathTransformBuffer(kPathXformBufferMinReserve * sizeof(float)/4)
    , fPipelineBuffer(kPipelineBufferMinReserve)
    , fDrawID(0) {
}

GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
    this->reset();
}

void GrInOrderDrawBuffer::onDrawBatch(GrBatch* batch,
                                      const PipelineInfo& pipelineInfo) {
    State* state = this->setupPipelineAndShouldDraw(batch, pipelineInfo);
    if (!state) {
        return;
    }

    GrTargetCommands::Cmd* cmd = fCommands->recordDrawBatch(state, batch);
    this->recordTraceMarkersIfNecessary(cmd);
}

void GrInOrderDrawBuffer::onStencilPath(const GrPipelineBuilder& pipelineBuilder,
                                        const GrPathProcessor* pathProc,
                                        const GrPath* path,
                                        const GrScissorState& scissorState,
                                        const GrStencilSettings& stencilSettings) {
    GrTargetCommands::Cmd* cmd = fCommands->recordStencilPath(pipelineBuilder,
                                                              pathProc, path, scissorState,
                                                              stencilSettings);
    this->recordTraceMarkersIfNecessary(cmd);
}

void GrInOrderDrawBuffer::onDrawPath(const GrPathProcessor* pathProc,
                                     const GrPath* path,
                                     const GrStencilSettings& stencilSettings,
                                     const PipelineInfo& pipelineInfo) {
    State* state = this->setupPipelineAndShouldDraw(pathProc, pipelineInfo);
    if (!state) {
        return;
    }
    GrTargetCommands::Cmd* cmd = fCommands->recordDrawPath(state, pathProc, path, stencilSettings);
    this->recordTraceMarkersIfNecessary(cmd);
}

void GrInOrderDrawBuffer::onDrawPaths(const GrPathProcessor* pathProc,
                                      const GrPathRange* pathRange,
                                      const void* indices,
                                      PathIndexType indexType,
                                      const float transformValues[],
                                      PathTransformType transformType,
                                      int count,
                                      const GrStencilSettings& stencilSettings,
                                      const PipelineInfo& pipelineInfo) {
    State* state = this->setupPipelineAndShouldDraw(pathProc, pipelineInfo);
    if (!state) {
        return;
    }
    GrTargetCommands::Cmd* cmd = fCommands->recordDrawPaths(state, this, pathProc, pathRange,
                                                            indices, indexType, transformValues,
                                                            transformType, count,
                                                            stencilSettings, pipelineInfo);
    this->recordTraceMarkersIfNecessary(cmd);
}

void GrInOrderDrawBuffer::onClear(const SkIRect* rect, GrColor color,
                                  bool canIgnoreRect, GrRenderTarget* renderTarget) {
    GrTargetCommands::Cmd* cmd = fCommands->recordClear(rect, color, canIgnoreRect, renderTarget);
    this->recordTraceMarkersIfNecessary(cmd);
}

void GrInOrderDrawBuffer::clearStencilClip(const SkIRect& rect,
                                           bool insideClip,
                                           GrRenderTarget* renderTarget) {
    GrTargetCommands::Cmd* cmd = fCommands->recordClearStencilClip(rect, insideClip, renderTarget);
    this->recordTraceMarkersIfNecessary(cmd);
}

void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) {
    if (!this->caps()->discardRenderTargetSupport()) {
        return;
    }

    GrTargetCommands::Cmd* cmd = fCommands->recordDiscard(renderTarget);
    this->recordTraceMarkersIfNecessary(cmd);
}

void GrInOrderDrawBuffer::onReset() {
    fCommands->reset();
    fPathIndexBuffer.rewind();
    fPathTransformBuffer.rewind();
    fGpuCmdMarkers.reset();

    fPrevState.reset(NULL);
    // Note, fPrevState points into fPipelineBuffer's allocation, so we have to reset first.
    // Furthermore, we have to reset fCommands before fPipelineBuffer too.
    if (fDrawID % kPipelineBufferHighWaterMark) {
        fPipelineBuffer.rewind();
    } else {
        fPipelineBuffer.reset();
    }
}

void GrInOrderDrawBuffer::onFlush() {
    fCommands->flush(this);
    ++fDrawID;
}

void GrInOrderDrawBuffer::onCopySurface(GrSurface* dst,
                                        GrSurface* src,
                                        const SkIRect& srcRect,
                                        const SkIPoint& dstPoint) {
    SkASSERT(this->getGpu()->canCopySurface(dst, src, srcRect, dstPoint));
    GrTargetCommands::Cmd* cmd = fCommands->recordCopySurface(dst, src, srcRect, dstPoint);
    this->recordTraceMarkersIfNecessary(cmd);
}

void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary(GrTargetCommands::Cmd* cmd) {
    if (!cmd) {
        return;
    }
    const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers();
    if (activeTraceMarkers.count() > 0) {
        if (cmd->isTraced()) {
            fGpuCmdMarkers[cmd->markerID()].addSet(activeTraceMarkers);
        } else {
            cmd->setMarkerID(fGpuCmdMarkers.count());
            fGpuCmdMarkers.push_back(activeTraceMarkers);
        }
    }
}

GrTargetCommands::State*
GrInOrderDrawBuffer::setupPipelineAndShouldDraw(const GrPrimitiveProcessor* primProc,
                                                const GrDrawTarget::PipelineInfo& pipelineInfo) {
    State* state = this->allocState(primProc);
    this->setupPipeline(pipelineInfo, state->pipelineLocation());

    if (state->getPipeline()->mustSkip()) {
        this->unallocState(state);
        return NULL;
    }

    state->fPrimitiveProcessor->initBatchTracker(&state->fBatchTracker,
                                                 state->getPipeline()->getInitBatchTracker());

    if (fPrevState && fPrevState->fPrimitiveProcessor.get() &&
        fPrevState->fPrimitiveProcessor->canMakeEqual(fPrevState->fBatchTracker,
                                                      *state->fPrimitiveProcessor,
                                                      state->fBatchTracker) &&
        fPrevState->getPipeline()->isEqual(*state->getPipeline())) {
        this->unallocState(state);
    } else {
        fPrevState.reset(state);
    }

    this->recordTraceMarkersIfNecessary(
            fCommands->recordXferBarrierIfNecessary(*fPrevState->getPipeline(), *this->caps()));
    return fPrevState;
}

GrTargetCommands::State*
GrInOrderDrawBuffer::setupPipelineAndShouldDraw(GrBatch* batch,
                                                const GrDrawTarget::PipelineInfo& pipelineInfo) {
    State* state = this->allocState();
    this->setupPipeline(pipelineInfo, state->pipelineLocation());

    if (state->getPipeline()->mustSkip()) {
        this->unallocState(state);
        return NULL;
    }

    batch->initBatchTracker(state->getPipeline()->getInitBatchTracker());

    if (fPrevState && !fPrevState->fPrimitiveProcessor.get() &&
        fPrevState->getPipeline()->isEqual(*state->getPipeline())) {
        this->unallocState(state);
    } else {
        fPrevState.reset(state);
    }

    this->recordTraceMarkersIfNecessary(
            fCommands->recordXferBarrierIfNecessary(*fPrevState->getPipeline(), *this->caps()));
    return fPrevState;
}
<commit_msg>revert reordering<commit_after>/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "GrInOrderDrawBuffer.h"

// We will use the reordering buffer, unless we have NVPR.
// TODO move NVPR to batch so we can reorder
static inline bool allow_reordering(const GrGpu* gpu) {
    //const GrCaps* caps = gpu->caps();
    //return caps && caps->shaderCaps() && !caps->shaderCaps()->pathRenderingSupport();
    return false;
}

GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrContext* context)
    : INHERITED(context)
    , fCommands(GrCommandBuilder::Create(context->getGpu(), allow_reordering(context->getGpu())))
    , fPathIndexBuffer(kPathIdxBufferMinReserve * sizeof(char)/4)
    , fPathTransformBuffer(kPathXformBufferMinReserve * sizeof(float)/4)
    , fPipelineBuffer(kPipelineBufferMinReserve)
    , fDrawID(0) {
}

GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
    this->reset();
}

void GrInOrderDrawBuffer::onDrawBatch(GrBatch* batch,
                                      const PipelineInfo& pipelineInfo) {
    State* state = this->setupPipelineAndShouldDraw(batch, pipelineInfo);
    if (!state) {
        return;
    }

    GrTargetCommands::Cmd* cmd = fCommands->recordDrawBatch(state, batch);
    this->recordTraceMarkersIfNecessary(cmd);
}

void GrInOrderDrawBuffer::onStencilPath(const GrPipelineBuilder& pipelineBuilder,
                                        const GrPathProcessor* pathProc,
                                        const GrPath* path,
                                        const GrScissorState& scissorState,
                                        const GrStencilSettings& stencilSettings) {
    GrTargetCommands::Cmd* cmd = fCommands->recordStencilPath(pipelineBuilder,
                                                              pathProc, path, scissorState,
                                                              stencilSettings);
    this->recordTraceMarkersIfNecessary(cmd);
}

void GrInOrderDrawBuffer::onDrawPath(const GrPathProcessor* pathProc,
                                     const GrPath* path,
                                     const GrStencilSettings& stencilSettings,
                                     const PipelineInfo& pipelineInfo) {
    State* state = this->setupPipelineAndShouldDraw(pathProc, pipelineInfo);
    if (!state) {
        return;
    }
    GrTargetCommands::Cmd* cmd = fCommands->recordDrawPath(state, pathProc, path, stencilSettings);
    this->recordTraceMarkersIfNecessary(cmd);
}

void GrInOrderDrawBuffer::onDrawPaths(const GrPathProcessor* pathProc,
                                      const GrPathRange* pathRange,
                                      const void* indices,
                                      PathIndexType indexType,
                                      const float transformValues[],
                                      PathTransformType transformType,
                                      int count,
                                      const GrStencilSettings& stencilSettings,
                                      const PipelineInfo& pipelineInfo) {
    State* state = this->setupPipelineAndShouldDraw(pathProc, pipelineInfo);
    if (!state) {
        return;
    }
    GrTargetCommands::Cmd* cmd = fCommands->recordDrawPaths(state, this, pathProc, pathRange,
                                                            indices, indexType, transformValues,
                                                            transformType, count,
                                                            stencilSettings, pipelineInfo);
    this->recordTraceMarkersIfNecessary(cmd);
}

void GrInOrderDrawBuffer::onClear(const SkIRect* rect, GrColor color,
                                  bool canIgnoreRect, GrRenderTarget* renderTarget) {
    GrTargetCommands::Cmd* cmd = fCommands->recordClear(rect, color, canIgnoreRect, renderTarget);
    this->recordTraceMarkersIfNecessary(cmd);
}

void GrInOrderDrawBuffer::clearStencilClip(const SkIRect& rect,
                                           bool insideClip,
                                           GrRenderTarget* renderTarget) {
    GrTargetCommands::Cmd* cmd = fCommands->recordClearStencilClip(rect, insideClip, renderTarget);
    this->recordTraceMarkersIfNecessary(cmd);
}

void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) {
    if (!this->caps()->discardRenderTargetSupport()) {
        return;
    }

    GrTargetCommands::Cmd* cmd = fCommands->recordDiscard(renderTarget);
    this->recordTraceMarkersIfNecessary(cmd);
}

void GrInOrderDrawBuffer::onReset() {
    fCommands->reset();
    fPathIndexBuffer.rewind();
    fPathTransformBuffer.rewind();
    fGpuCmdMarkers.reset();

    fPrevState.reset(NULL);
    // Note, fPrevState points into fPipelineBuffer's allocation, so we have to reset first.
    // Furthermore, we have to reset fCommands before fPipelineBuffer too.
    if (fDrawID % kPipelineBufferHighWaterMark) {
        fPipelineBuffer.rewind();
    } else {
        fPipelineBuffer.reset();
    }
}

void GrInOrderDrawBuffer::onFlush() {
    fCommands->flush(this);
    ++fDrawID;
}

void GrInOrderDrawBuffer::onCopySurface(GrSurface* dst,
                                        GrSurface* src,
                                        const SkIRect& srcRect,
                                        const SkIPoint& dstPoint) {
    SkASSERT(this->getGpu()->canCopySurface(dst, src, srcRect, dstPoint));
    GrTargetCommands::Cmd* cmd = fCommands->recordCopySurface(dst, src, srcRect, dstPoint);
    this->recordTraceMarkersIfNecessary(cmd);
}

void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary(GrTargetCommands::Cmd* cmd) {
    if (!cmd) {
        return;
    }
    const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers();
    if (activeTraceMarkers.count() > 0) {
        if (cmd->isTraced()) {
            fGpuCmdMarkers[cmd->markerID()].addSet(activeTraceMarkers);
        } else {
            cmd->setMarkerID(fGpuCmdMarkers.count());
            fGpuCmdMarkers.push_back(activeTraceMarkers);
        }
    }
}

GrTargetCommands::State*
GrInOrderDrawBuffer::setupPipelineAndShouldDraw(const GrPrimitiveProcessor* primProc,
                                                const GrDrawTarget::PipelineInfo& pipelineInfo) {
    State* state = this->allocState(primProc);
    this->setupPipeline(pipelineInfo, state->pipelineLocation());

    if (state->getPipeline()->mustSkip()) {
        this->unallocState(state);
        return NULL;
    }

    state->fPrimitiveProcessor->initBatchTracker(&state->fBatchTracker,
                                                 state->getPipeline()->getInitBatchTracker());

    if (fPrevState && fPrevState->fPrimitiveProcessor.get() &&
        fPrevState->fPrimitiveProcessor->canMakeEqual(fPrevState->fBatchTracker,
                                                      *state->fPrimitiveProcessor,
                                                      state->fBatchTracker) &&
        fPrevState->getPipeline()->isEqual(*state->getPipeline())) {
        this->unallocState(state);
    } else {
        fPrevState.reset(state);
    }

    this->recordTraceMarkersIfNecessary(
            fCommands->recordXferBarrierIfNecessary(*fPrevState->getPipeline(), *this->caps()));
    return fPrevState;
}

GrTargetCommands::State*
GrInOrderDrawBuffer::setupPipelineAndShouldDraw(GrBatch* batch,
                                                const GrDrawTarget::PipelineInfo& pipelineInfo) {
    State* state = this->allocState();
    this->setupPipeline(pipelineInfo, state->pipelineLocation());

    if (state->getPipeline()->mustSkip()) {
        this->unallocState(state);
        return NULL;
    }

    batch->initBatchTracker(state->getPipeline()->getInitBatchTracker());

    if (fPrevState && !fPrevState->fPrimitiveProcessor.get() &&
        fPrevState->getPipeline()->isEqual(*state->getPipeline())) {
        this->unallocState(state);
    } else {
        fPrevState.reset(state);
    }

    this->recordTraceMarkersIfNecessary(
            fCommands->recordXferBarrierIfNecessary(*fPrevState->getPipeline(), *this->caps()));
    return fPrevState;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdint>
#include <string>
#include <sys/types.h>
#include <dirent.h>
#include <sstream>
#include <sys/stat.h>
#include <cstring>
#include "message.H"
#include <time.h>
#include <stddef.h>
#include <cstdio>

const uint32_t g_eyecatcher = 0x4F424D43; // OBMC
const uint16_t g_version    = 1;

struct logheader_t {
	uint32_t eyecatcher;
	uint16_t version;
	uint16_t logid;
	time_t   timestamp;
	uint16_t detailsoffset;
	uint16_t messagelen;
	uint16_t severitylen;
	uint16_t associationlen;
	uint16_t reportedbylen;
	uint16_t debugdatalen;
};

event_manager::event_manager(string path)
{
	uint16_t x;
	eventpath = path;
	latestid = 0;
	dirp = NULL;
	logcount = 0;

	// examine the files being managed and advance latestid to that value
	while ( (x = next_log()) ) {
		logcount++;
		if ( x > latestid )
			latestid = x;
	}

	return;
}

event_manager::~event_manager()
{
	if (dirp)
		closedir(dirp);

	return;
}

bool event_manager::is_file_a_log(string str)
{
	std::ostringstream buffer;
	ifstream f;
	logheader_t hdr;

	if (!str.compare("."))
		return 0;

	if (!str.compare(".."))
		return 0;

	buffer << eventpath << "/" << str;

	f.open( buffer.str(), ios::binary);

	if (!f.good()) {
		return 0;
	}

	f.read((char*)&hdr, sizeof(hdr));

	if (hdr.eyecatcher != g_eyecatcher)
		return 0;

	return 1;
}

uint16_t event_manager::log_count(void)
{
	return logcount;
}
uint16_t event_manager::latest_log_id(void)
{
	return latestid;
}
uint16_t event_manager::new_log_id(void)
{
	return ++latestid;
}
void event_manager::next_log_refresh(void)
{
	if (dirp) {
		closedir(dirp);
		dirp = NULL;
	}

	return;
}

uint16_t event_manager::next_log(void)
{
	std::ostringstream buffer;
	struct dirent *ent;
	uint16_t id;

	if (dirp == NULL)
		dirp = opendir(eventpath.c_str());

	if (dirp) {
		do {
			ent = readdir(dirp);

			if (ent == NULL)
				break;

			string str(ent->d_name);

			if (is_file_a_log(str)) {
				id = (uint16_t) atoi(str.c_str());
				break;
			}

		} while( 1 );
	} else {
		cerr << "Error opening directory " << eventpath << endl;
		ent = NULL;
		id = 0;
	}

	if (ent == NULL) {
		closedir(dirp);
		dirp = NULL;
	}

	return  ((ent == NULL) ? 0 : id);
}

uint16_t event_manager::create(event_record_t *rec)
{
	rec->logid = new_log_id();
	rec->timestamp = time(NULL);

	return create_log_event(rec);
}

inline uint16_t getlen(const char *s)
{
	return (uint16_t) (1 + strlen(s));
}

size_t event_manager::get_managed_size(void)
{
	DIR *dirp;
	std::ostringstream buffer;
	struct dirent *ent;
	ifstream f;

	size_t db_size = 0;

	dirp = opendir(eventpath.c_str());

	if (dirp) {
		while ( (ent = readdir(dirp)) != NULL ) {

			string str(ent->d_name);

			if (is_file_a_log(str)) {

				buffer.str("");
				buffer << eventpath << "/" << str.c_str();

				f.open(buffer.str() , ios::in|ios::binary|ios::ate);
				db_size += f.tellg();
				f.close();
			}
		}
	}

	closedir(dirp);

	return (db_size);
}

uint16_t event_manager::create_log_event(event_record_t *rec)
{
	std::ostringstream buffer;
	ofstream myfile;
	logheader_t hdr = {0};

	buffer << eventpath << "/" << int(rec->logid) ;

	hdr.eyecatcher     = g_eyecatcher;
	hdr.version        = g_version;
	hdr.logid          = rec->logid;
	hdr.timestamp      = rec->timestamp;
	hdr.detailsoffset  = offsetof(logheader_t, messagelen);
	hdr.messagelen     = getlen(rec->message);
	hdr.severitylen    = getlen(rec->severity);
	hdr.associationlen = getlen(rec->association);
	hdr.reportedbylen  = getlen(rec->reportedby);
	hdr.debugdatalen   = rec->n;

	myfile.open(buffer.str() , ios::out|ios::binary);
	myfile.write((char*) &hdr, sizeof(hdr));
	myfile.write((char*) rec->message, hdr.messagelen);
	myfile.write((char*) rec->severity, hdr.severitylen);
	myfile.write((char*) rec->association, hdr.associationlen);
	myfile.write((char*) rec->reportedby, hdr.reportedbylen);
	myfile.write((char*) rec->p, hdr.debugdatalen);
	myfile.close();

	logcount++;

	return rec->logid;
}

int event_manager::open(uint16_t logid, event_record_t **rec)
{
	std::ostringstream buffer;
	ifstream f;
	logheader_t hdr;

	buffer << eventpath << "/" << int(logid);

	f.open( buffer.str(), ios::binary );

	if (!f.good()) {
		return 0;
	}

	*rec = new event_record_t;

	f.read((char*)&hdr, sizeof(hdr));

	(*rec)->logid     = hdr.logid;
	(*rec)->timestamp = hdr.timestamp;

	(*rec)->message = new char[hdr.messagelen];
	f.read((*rec)->message, hdr.messagelen);

	(*rec)->severity = new char[hdr.severitylen];
	f.read((*rec)->severity, hdr.severitylen);

	(*rec)->association = new char[hdr.associationlen];
	f.read((*rec)->association, hdr.associationlen);

	(*rec)->reportedby = new char[hdr.reportedbylen];
	f.read((*rec)->reportedby, hdr.reportedbylen);

	(*rec)->p = new uint8_t[hdr.debugdatalen];
	f.read((char*)(*rec)->p, hdr.debugdatalen);
	(*rec)->n = hdr.debugdatalen;

	f.close();
	return logid;
}

void event_manager::close(event_record_t *rec)
{
	delete[] rec->message;
	delete[] rec->severity;
	delete[] rec->association;
	delete[] rec->reportedby;
	delete[] rec->p;
	delete rec;

	logcount--;
	return ;
}

int event_manager::remove(uint16_t logid)
{
	std::stringstream buffer;
	string s;

	buffer << eventpath << "/" << int(logid);

	s = buffer.str();
	std::remove(s.c_str());

	return 0;
}
<commit_msg>Add flush after writing<commit_after>#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdint>
#include <string>
#include <sys/types.h>
#include <dirent.h>
#include <sstream>
#include <sys/stat.h>
#include <cstring>
#include "message.H"
#include <time.h>
#include <stddef.h>
#include <cstdio>

const uint32_t g_eyecatcher = 0x4F424D43; // OBMC
const uint16_t g_version    = 1;

struct logheader_t {
	uint32_t eyecatcher;
	uint16_t version;
	uint16_t logid;
	time_t   timestamp;
	uint16_t detailsoffset;
	uint16_t messagelen;
	uint16_t severitylen;
	uint16_t associationlen;
	uint16_t reportedbylen;
	uint16_t debugdatalen;
};

event_manager::event_manager(string path)
{
	uint16_t x;
	eventpath = path;
	latestid = 0;
	dirp = NULL;
	logcount = 0;

	// examine the files being managed and advance latestid to that value
	while ( (x = next_log()) ) {
		logcount++;
		if ( x > latestid )
			latestid = x;
	}

	return;
}

event_manager::~event_manager()
{
	if (dirp)
		closedir(dirp);

	return;
}

bool event_manager::is_file_a_log(string str)
{
	std::ostringstream buffer;
	ifstream f;
	logheader_t hdr;

	if (!str.compare("."))
		return 0;

	if (!str.compare(".."))
		return 0;

	buffer << eventpath << "/" << str;

	f.open( buffer.str(), ios::binary);

	if (!f.good()) {
		f.close();
		return 0;
	}

	f.read((char*)&hdr, sizeof(hdr));
	f.close();

	if (hdr.eyecatcher != g_eyecatcher)
		return 0;

	return 1;
}

uint16_t event_manager::log_count(void)
{
	return logcount;
}
uint16_t event_manager::latest_log_id(void)
{
	return latestid;
}
uint16_t event_manager::new_log_id(void)
{
	return ++latestid;
}
void event_manager::next_log_refresh(void)
{
	if (dirp) {
		closedir(dirp);
		dirp = NULL;
	}

	return;
}

uint16_t event_manager::next_log(void)
{
	std::ostringstream buffer;
	struct dirent *ent;
	uint16_t id;

	if (dirp == NULL)
		dirp = opendir(eventpath.c_str());

	if (dirp) {
		do {
			ent = readdir(dirp);

			if (ent == NULL)
				break;

			string str(ent->d_name);

			if (is_file_a_log(str)) {
				id = (uint16_t) atoi(str.c_str());
				break;
			}

		} while( 1 );
	} else {
		cerr << "Error opening directory " << eventpath << endl;
		ent = NULL;
		id = 0;
	}

	if (ent == NULL) {
		closedir(dirp);
		dirp = NULL;
	}

	return  ((ent == NULL) ? 0 : id);
}

uint16_t event_manager::create(event_record_t *rec)
{
	rec->logid = new_log_id();
	rec->timestamp = time(NULL);

	return create_log_event(rec);
}

inline uint16_t getlen(const char *s)
{
	return (uint16_t) (1 + strlen(s));
}

size_t event_manager::get_managed_size(void)
{
	DIR *dirp;
	std::ostringstream buffer;
	struct dirent *ent;
	ifstream f;

	size_t db_size = 0;

	dirp = opendir(eventpath.c_str());

	if (dirp) {
		while ( (ent = readdir(dirp)) != NULL ) {

			string str(ent->d_name);

			if (is_file_a_log(str)) {

				buffer.str("");
				buffer << eventpath << "/" << str.c_str();

				f.open(buffer.str() , ios::in|ios::binary|ios::ate);
				db_size += f.tellg();
				f.close();
			}
		}
	}

	closedir(dirp);

	return (db_size);
}

uint16_t event_manager::create_log_event(event_record_t *rec)
{
	std::ostringstream buffer;
	ofstream myfile;
	logheader_t hdr = {0};

	buffer << eventpath << "/" << int(rec->logid) ;

	hdr.eyecatcher     = g_eyecatcher;
	hdr.version        = g_version;
	hdr.logid          = rec->logid;
	hdr.timestamp      = rec->timestamp;
	hdr.detailsoffset  = offsetof(logheader_t, messagelen);
	hdr.messagelen     = getlen(rec->message);
	hdr.severitylen    = getlen(rec->severity);
	hdr.associationlen = getlen(rec->association);
	hdr.reportedbylen  = getlen(rec->reportedby);
	hdr.debugdatalen   = rec->n;

	myfile.open(buffer.str() , ios::out|ios::binary);
	myfile.write((char*) &hdr, sizeof(hdr));
	myfile.write((char*) rec->message, hdr.messagelen);
	myfile.write((char*) rec->severity, hdr.severitylen);
	myfile.write((char*) rec->association, hdr.associationlen);
	myfile.write((char*) rec->reportedby, hdr.reportedbylen);
	myfile.write((char*) rec->p, hdr.debugdatalen);
	myfile.flush();
	myfile.close();

	logcount++;

	return rec->logid;
}

int event_manager::open(uint16_t logid, event_record_t **rec)
{
	std::ostringstream buffer;
	ifstream f;
	logheader_t hdr;

	buffer << eventpath << "/" << int(logid);

	f.open( buffer.str(), ios::binary );

	if (!f.good()) {
		return 0;
	}

	*rec = new event_record_t;

	f.read((char*)&hdr, sizeof(hdr));

	(*rec)->logid     = hdr.logid;
	(*rec)->timestamp = hdr.timestamp;

	(*rec)->message = new char[hdr.messagelen];
	f.read((*rec)->message, hdr.messagelen);

	(*rec)->severity = new char[hdr.severitylen];
	f.read((*rec)->severity, hdr.severitylen);

	(*rec)->association = new char[hdr.associationlen];
	f.read((*rec)->association, hdr.associationlen);

	(*rec)->reportedby = new char[hdr.reportedbylen];
	f.read((*rec)->reportedby, hdr.reportedbylen);

	(*rec)->p = new uint8_t[hdr.debugdatalen];
	f.read((char*)(*rec)->p, hdr.debugdatalen);
	(*rec)->n = hdr.debugdatalen;

	f.close();
	return logid;
}

void event_manager::close(event_record_t *rec)
{
	delete[] rec->message;
	delete[] rec->severity;
	delete[] rec->association;
	delete[] rec->reportedby;
	delete[] rec->p;
	delete rec;

	logcount--;
	return ;
}

int event_manager::remove(uint16_t logid)
{
	std::stringstream buffer;
	string s;

	buffer << eventpath << "/" << int(logid);

	s = buffer.str();
	std::remove(s.c_str());

	return 0;
}
<|endoftext|>


<commit_before>/*
 * References:
 *   [FTE1] http://eprint.iacr.org/2012/494.pdf
 *   [FTE2] (to appear summer 2014)
 */

#include <math.h>

#include "fte/fte.h"
#include "ffx/ffx.h"

namespace fte {

Fte::Fte() {
  ffx_ = ffx::Ffx(kFfxRadix);
  key_is_set_ = false;
  languages_are_set_ = false;
}

/*
 * Here we set our input/output langauges and verify that the output langauge has
 * capacity at least as large as the input language.
 */
bool Fte::SetLanguages(const std::string & plaintext_dfa,
                       uint32_t plaintext_max_len,
                       const std::string & ciphertext_dfa,
                       uint32_t ciphertext_max_len) {

  plaintext_ranker_ = ranking::DfaRanker();
  plaintext_ranker_.SetLanguage(plaintext_dfa, plaintext_max_len);
  plaintext_ranker_.WordsInLanguage(&words_in_plaintext_language_);
  plaintext_language_capacity_in_bits_ = mpz_sizeinbase(words_in_plaintext_language_.get_mpz_t(),
                                         kFfxRadix);

  bool languages_are_the_same = (plaintext_dfa == ciphertext_dfa) && (plaintext_max_len == ciphertext_max_len);
  if (languages_are_the_same) {
    ciphertext_ranker_ = plaintext_ranker_;
  } else {
    ciphertext_ranker_ = ranking::DfaRanker();
    ciphertext_ranker_.SetLanguage(ciphertext_dfa, ciphertext_max_len);
  }

  ciphertext_ranker_.WordsInLanguage(&words_in_ciphertext_language_);
  ciphertext_language_capacity_in_bits_ = mpz_sizeinbase(
      words_in_ciphertext_language_.get_mpz_t(), kFfxRadix);

  if(words_in_plaintext_language_ > words_in_ciphertext_language_) {
    return false;
  }

  languages_are_set_ = true;

  return true;
}

bool Fte::set_key(const std::string & key) {
  bool success = ffx_.SetKey(key);
  key_is_set_ = success;
  return success;
}

/*
 * This is an implementation of rank-encipher-unrank, as described in [FTE2].
 * We perform cycle walking to ensure that we have a ciphertext in the input
 * domain of the ciphertext ranker.
 */
bool Fte::Encrypt(const std::string & plaintext,
                  std::string * ciphertext) {

  if (!key_is_set_) {
    return false;
  }

  if (!languages_are_set_) {
    return false;
  }

  mpz_class plaintext_rank;
  plaintext_ranker_.Rank(plaintext, &plaintext_rank);
  mpz_class C = 0;
  ffx_.Encrypt(plaintext_rank, ciphertext_language_capacity_in_bits_, &C);
  while (C >= words_in_ciphertext_language_) {
    ffx_.Encrypt(C, ciphertext_language_capacity_in_bits_, &C);
  }
  ciphertext_ranker_.Unrank(C, ciphertext);

  return true;
}

/*
 * Here we recover a plaintext using rank-decipher-unrank.
 * See [FTE2] for more details.
 */
bool Fte::Decrypt(const std::string & ciphertext,
                  std::string * plaintext) {

  if (!key_is_set_) {
    return false;
  }

  if (!languages_are_set_) {
    return false;
  }

  mpz_class C;
  ciphertext_ranker_.Rank(ciphertext, &C);
  mpz_class plaintext_rank = 0;
  ffx_.Decrypt(C, ciphertext_language_capacity_in_bits_, &plaintext_rank);
  while (plaintext_rank >= words_in_plaintext_language_) {
    ffx_.Decrypt(plaintext_rank, ciphertext_language_capacity_in_bits_, &plaintext_rank);
  }
  plaintext_ranker_.Unrank(plaintext_rank, plaintext);

  return true;
}

} // namespace fte
<commit_msg>Issue #13: use the plaintext size as the VIL-blockcipher width<commit_after>/*
 * References:
 *   [FTE1] http://eprint.iacr.org/2012/494.pdf
 *   [FTE2] (to appear summer 2014)
 */

#include <math.h>

#include "fte/fte.h"
#include "ffx/ffx.h"

namespace fte {

Fte::Fte() {
  ffx_ = ffx::Ffx(kFfxRadix);
  key_is_set_ = false;
  languages_are_set_ = false;
}

/*
 * Here we set our input/output langauges and verify that the output langauge has
 * capacity at least as large as the input language.
 */
bool Fte::SetLanguages(const std::string & plaintext_dfa,
                       uint32_t plaintext_max_len,
                       const std::string & ciphertext_dfa,
                       uint32_t ciphertext_max_len) {

  plaintext_ranker_ = ranking::DfaRanker();
  plaintext_ranker_.SetLanguage(plaintext_dfa, plaintext_max_len);
  plaintext_ranker_.WordsInLanguage(&words_in_plaintext_language_);
  plaintext_language_capacity_in_bits_ = mpz_sizeinbase(words_in_plaintext_language_.get_mpz_t(),
                                         kFfxRadix);

  bool languages_are_the_same = (plaintext_dfa == ciphertext_dfa) && (plaintext_max_len == ciphertext_max_len);
  if (languages_are_the_same) {
    ciphertext_ranker_ = plaintext_ranker_;
  } else {
    ciphertext_ranker_ = ranking::DfaRanker();
    ciphertext_ranker_.SetLanguage(ciphertext_dfa, ciphertext_max_len);
  }

  ciphertext_ranker_.WordsInLanguage(&words_in_ciphertext_language_);
  ciphertext_language_capacity_in_bits_ = mpz_sizeinbase(
      words_in_ciphertext_language_.get_mpz_t(), kFfxRadix);

  if(words_in_plaintext_language_ > words_in_ciphertext_language_) {
    return false;
  }

  languages_are_set_ = true;

  return true;
}

bool Fte::set_key(const std::string & key) {
  bool success = ffx_.SetKey(key);
  key_is_set_ = success;
  return success;
}

/*
 * This is an implementation of rank-encipher-unrank, as described in [FTE2].
 * We perform cycle walking to ensure that we have a ciphertext in the input
 * domain of the ciphertext ranker.
 */
bool Fte::Encrypt(const std::string & plaintext,
                  std::string * ciphertext) {

  if (!key_is_set_) {
    return false;
  }

  if (!languages_are_set_) {
    return false;
  }

  mpz_class plaintext_rank;
  plaintext_ranker_.Rank(plaintext, &plaintext_rank);
  mpz_class C = 0;
  ffx_.Encrypt(plaintext_rank, plaintext_language_capacity_in_bits_, &C);
  while (C >= words_in_ciphertext_language_) {
    ffx_.Encrypt(C, plaintext_language_capacity_in_bits_, &C);
  }
  ciphertext_ranker_.Unrank(C, ciphertext);

  return true;
}

/*
 * Here we recover a plaintext using rank-decipher-unrank.
 * See [FTE2] for more details.
 */
bool Fte::Decrypt(const std::string & ciphertext,
                  std::string * plaintext) {

  if (!key_is_set_) {
    return false;
  }

  if (!languages_are_set_) {
    return false;
  }

  mpz_class C;
  ciphertext_ranker_.Rank(ciphertext, &C);
  mpz_class plaintext_rank = 0;
  ffx_.Decrypt(C, plaintext_language_capacity_in_bits_, &plaintext_rank);
  while (plaintext_rank >= words_in_plaintext_language_) {
    ffx_.Decrypt(plaintext_rank, plaintext_language_capacity_in_bits_, &plaintext_rank);
  }
  plaintext_ranker_.Unrank(plaintext_rank, plaintext);

  return true;
}

} // namespace fte
<|endoftext|>


<commit_before>#include "mainwindow.h"
#include "types.h"
#include "connectiontester.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect(ui->startButton, SIGNAL(clicked()), this, SLOT(startClicked()));
    connect(ui->actionConnection_does_not_work, SIGNAL(triggered()), this, SLOT(noConnectionClicked()));
    connect(ui->actionConnection_is_slow, SIGNAL(triggered()), this, SLOT(connectionSlowClicked()));
    connect(ui->action_Quit, SIGNAL(triggered()), qApp, SLOT(quit()));

#ifndef Q_OS_MAC // Mac applications don't use icons
    setWindowIcon(QIcon(":/tray.png"));
#endif // Q_OS_MAC

    // No reason to continue when there is no system tray supported
    if (!QSystemTrayIcon::isSystemTrayAvailable())
        return;

    QIcon trayIcon;
#ifdef Q_OS_MAC
    trayIcon.addFile(":/tray_mac.png");
    trayIcon.addFile(":/tray_mac_active.png", QSize(), QIcon::Selected);
#else // Q_OS_MAC
    trayIcon.addFile(":/tray.png");
#endif // Q_OS_MAC
    m_tray.setIcon(trayIcon);
    m_tray.setContextMenu(ui->menu_File);
    m_tray.setToolTip(tr("mPlane client"));
    m_tray.show();
}

MainWindow::~MainWindow()
{
    m_tray.hide();
    delete ui;
}

void MainWindow::setClient(Client *client)
{
    if (client == m_client)
        return;

    if (m_client) {
        disconnect(m_client.data(), SIGNAL(statusChanged()), this, SLOT(statusChanged()));
    }

    m_client = client;

    if (m_client) {
        connect(m_client.data(), SIGNAL(statusChanged()), this, SLOT(statusChanged()));

        // Update methods
        statusChanged();

        // Update variables
        m_negotiator.setManagerSocket(m_client->managerSocket());
    }
}

Client *MainWindow::client() const
{
    return m_client;
}

void MainWindow::startClicked()
{
    // Don't continue when client is no registered
    if (m_client->status() != Client::Registered) {
        return;
    }

    Q_ASSERT(m_client);
    RemoteInfoList remotes = m_client->remoteInfo();
    Q_ASSERT(!remotes.isEmpty());
    RemoteInfo remote = remotes.first();

    m_negotiator.sendRequest(remote.peerAddress, remote.peerPort);
}

void MainWindow::noConnectionClicked()
{
    ConnectionTester tester;
    connect(&tester, SIGNAL(message(QString,MessageType)), ui->textEdit, SLOT(append(QString)));
    tester.start();
}

void MainWindow::connectionSlowClicked()
{
}

void MainWindow::statusChanged()
{
    ui->startButton->setEnabled( m_client->status() == Client::Registered );
    ui->statusbar->showMessage( enumToString(Client, "Status", m_client->status()) );
}
<commit_msg>Mac can't handle selected state in tray area, so we remove it.<commit_after>#include "mainwindow.h"
#include "types.h"
#include "connectiontester.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect(ui->startButton, SIGNAL(clicked()), this, SLOT(startClicked()));
    connect(ui->actionConnection_does_not_work, SIGNAL(triggered()), this, SLOT(noConnectionClicked()));
    connect(ui->actionConnection_is_slow, SIGNAL(triggered()), this, SLOT(connectionSlowClicked()));
    connect(ui->action_Quit, SIGNAL(triggered()), qApp, SLOT(quit()));

#ifndef Q_OS_MAC // Mac applications don't use icons
    setWindowIcon(QIcon(":/tray.png"));
#endif // Q_OS_MAC

    // No reason to continue when there is no system tray supported
    if (!QSystemTrayIcon::isSystemTrayAvailable())
        return;

    QIcon trayIcon;
#ifdef Q_OS_MAC
    trayIcon.addFile(":/tray_mac.png");
#else // Q_OS_MAC
    trayIcon.addFile(":/tray.png");
#endif // Q_OS_MAC
    m_tray.setIcon(trayIcon);
    m_tray.setContextMenu(ui->menu_File);
    m_tray.setToolTip(tr("mPlane client"));
    m_tray.show();
}

MainWindow::~MainWindow()
{
    m_tray.hide();
    delete ui;
}

void MainWindow::setClient(Client *client)
{
    if (client == m_client)
        return;

    if (m_client) {
        disconnect(m_client.data(), SIGNAL(statusChanged()), this, SLOT(statusChanged()));
    }

    m_client = client;

    if (m_client) {
        connect(m_client.data(), SIGNAL(statusChanged()), this, SLOT(statusChanged()));

        // Update methods
        statusChanged();

        // Update variables
        m_negotiator.setManagerSocket(m_client->managerSocket());
    }
}

Client *MainWindow::client() const
{
    return m_client;
}

void MainWindow::startClicked()
{
    // Don't continue when client is no registered
    if (m_client->status() != Client::Registered) {
        return;
    }

    Q_ASSERT(m_client);
    RemoteInfoList remotes = m_client->remoteInfo();
    Q_ASSERT(!remotes.isEmpty());
    RemoteInfo remote = remotes.first();

    m_negotiator.sendRequest(remote.peerAddress, remote.peerPort);
}

void MainWindow::noConnectionClicked()
{
    ConnectionTester tester;
    connect(&tester, SIGNAL(message(QString,MessageType)), ui->textEdit, SLOT(append(QString)));
    tester.start();
}

void MainWindow::connectionSlowClicked()
{
}

void MainWindow::statusChanged()
{
    ui->startButton->setEnabled( m_client->status() == Client::Registered );
    ui->statusbar->showMessage( enumToString(Client, "Status", m_client->status()) );
}
<|endoftext|>


<commit_before>/**
 * \file
 * <!--
 * Copyright 2015 Develer S.r.l. (http://www.develer.com/)
 * -->
 *
 * \brief main cutecom-ng window
 *
 * \author Aurelien Rainone <aurelien@develer.org>
 */

#include <algorithm>
#include <iterator>

#include <QUiLoader>
#include <QLineEdit>
#include <QPropertyAnimation>

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "connectdialog.h"
#include "sessionmanager.h"
#include "outputmanager.h"
#include "searchhighlighter.h"

/// line ending char appended to the commands sent to the serial port
const QString LINE_ENDING = "\n";

/// maximum count of document blocks for the bootom output
const int MAX_OUTPUT_LINES = 100;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    search_widget(0),
    search_input(0)
{
    ui->setupUi(this);

    // create session and output managers
    output_mgr = new OutputManager(this);
    session_mgr = new SessionManager(this);
    connect_dlg = new ConnectDialog(this);

    // load search widget and hide it
    QUiLoader loader;
    QFile file(":/searchwidget.ui");
    file.open(QFile::ReadOnly);
    search_widget = loader.load(&file, ui->mainOutput);
    Q_ASSERT_X(search_widget, "MainWindow::MainWindow", "error while loading searchwidget.ui");
    file.close();

    search_input = search_widget->findChild<QLineEdit*>("searchInput");

    Q_ASSERT_X(search_input, "MainWindow::MainWindow", "didn't find searchInput");

    // to make widget appear on top of : NOT WORKING
//    search_widget->setWindowFlags(search_widget->windowFlags() | Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint);
//    search_widget->setWindowModality(Qt::WindowModal);
    search_widget->hide();

    // show connection dialog
    connect(ui->connectButton, &QAbstractButton::clicked, connect_dlg, &ConnectDialog::show);

    // handle reception of new data from serial port
    connect(session_mgr, &SessionManager::dataReceived, this, &MainWindow::handleDataReceived);

    // get data formatted for display and show it in output view
    connect(output_mgr, &OutputManager::dataConverted, this, &MainWindow::addDataToView);

    // get data formatted for display and show it in output view
    connect(ui->inputBox, &HistoryComboBox::lineEntered, this, &MainWindow::handleNewInput);

    // clear output manager buffer at session start
    connect(session_mgr, &SessionManager::sessionStarted, output_mgr, &OutputManager::clear);

    // clear output text
    connect(session_mgr, &SessionManager::sessionStarted, ui->mainOutput, &QPlainTextEdit::clear);

    // call openSession when user accepts/closes connection dialog
    connect(connect_dlg, &ConnectDialog::openDeviceClicked, session_mgr, &SessionManager::openSession);

    connect(ui->splitOutputBtn, &QToolButton::clicked, this, &MainWindow::toggleOutputSplitter);

    // additional configuration for bottom output
    ui->bottomOutput->hide();
    ui->bottomOutput->document()->setMaximumBlockCount(MAX_OUTPUT_LINES);
    ui->bottomOutput->viewport()->installEventFilter(this);

    // create the search results highlighter and connect search-related signals/slots
    search_highlighter = new SearchHighlighter(ui->mainOutput->document());

    connect(ui->searchButton, &QToolButton::toggled, this, &MainWindow::showSearchWidget);
    connect(search_input, &QLineEdit::textChanged, search_highlighter, &SearchHighlighter::setSearchString);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::handleNewInput(QString entry)
{
    // if session is not open, this also keeps user input
    if (session_mgr->isSessionOpen())
    {
        entry.append(LINE_ENDING);
        session_mgr->sendToSerial(entry.toLocal8Bit());
        ui->inputBox->clearEditText();
    }
}

void MainWindow::addDataToView(const QString & textdata)
{
    // problem : QTextEdit interprets a '\r' as a new line, so if a buffer ending
    //           with '\r\n' happens to be cut in the middle, there will be 1 extra
    //           line jump in the QTextEdit. To prevent we remove ending '\r' and
    //           prepend them to the next received buffer

    // flag indicating that the previously received buffer ended with CR
    static bool prev_ends_with_CR = false;

    QString newdata;
    if (prev_ends_with_CR)
    {
        // CR was removed at the previous buffer, so now we prepend it
        newdata.append('\r');
        prev_ends_with_CR = false;
    }

    if (textdata.length() > 0)
    {
        QString::const_iterator end_cit = textdata.cend();
        if (textdata.endsWith('\r'))
        {
            // if buffer ends with CR, we don't copy it
            end_cit--;
            prev_ends_with_CR = true;
        }
        std::copy(textdata.begin(), end_cit, std::back_inserter(newdata));
    }

    // record end cursor position before adding text
    QTextCursor prev_end_cursor(ui->mainOutput->document());
    prev_end_cursor.movePosition(QTextCursor::End);

    if (ui->bottomOutput->isVisible())
    {
        // append text to the top output and stay at current position
        QTextCursor cursor(ui->mainOutput->document());
        cursor.movePosition(QTextCursor::End);
        cursor.insertText(newdata);
    }
    else
    {
        // append text to the top output and scroll down
        ui->mainOutput->moveCursor(QTextCursor::End);
        ui->mainOutput->insertPlainText(newdata);
    }

    // append text to bottom output and scroll
    ui->bottomOutput->moveCursor(QTextCursor::End);
    ui->bottomOutput->insertPlainText(newdata);

//    handleSearchTextChanged(search_input->text());
}

void MainWindow::handleDataReceived(const QByteArray &data)
{
    (*output_mgr) << data;
}

void MainWindow::toggleOutputSplitter()
{
    ui->bottomOutput->setVisible(!ui->bottomOutput->isVisible());
}

bool MainWindow::eventFilter(QObject *target, QEvent *event)
{
    if (event->type() == QEvent::Wheel)
        return true;

    // base class behaviour
    return QMainWindow::eventFilter(target, event);
}

void MainWindow::resizeEvent(QResizeEvent *event)
{
    // todo :remove hardcoded values
    search_widget->setGeometry(event->size().width() - search_widget->width() - 40, -2, 300, 40);

    // base class implementations
    QMainWindow::resizeEvent(event);
}

void MainWindow::showSearchWidget(bool show)
{
    QPropertyAnimation *animation = new QPropertyAnimation(search_widget, "geometry");
    animation->setDuration(150);

    QRect showed_pos(this->size().width() - search_widget->width() - 40, -2, 300, 40);
    QRect hidden_pos(this->size().width() - search_widget->width() - 40, -40, 300, 40);

    animation->setStartValue(show ? hidden_pos : showed_pos);
    animation->setEndValue(show ? showed_pos : hidden_pos);

    animation->start();
    search_widget->setVisible(true);
}
<commit_msg>hide search widget on ESC keypress<commit_after>/**
 * \file
 * <!--
 * Copyright 2015 Develer S.r.l. (http://www.develer.com/)
 * -->
 *
 * \brief main cutecom-ng window
 *
 * \author Aurelien Rainone <aurelien@develer.org>
 */

#include <algorithm>
#include <iterator>

#include <QUiLoader>
#include <QLineEdit>
#include <QPropertyAnimation>

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "connectdialog.h"
#include "sessionmanager.h"
#include "outputmanager.h"
#include "searchhighlighter.h"

/// line ending char appended to the commands sent to the serial port
const QString LINE_ENDING = "\n";

/// maximum count of document blocks for the bootom output
const int MAX_OUTPUT_LINES = 100;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    search_widget(0),
    search_input(0)
{
    ui->setupUi(this);

    // create session and output managers
    output_mgr = new OutputManager(this);
    session_mgr = new SessionManager(this);
    connect_dlg = new ConnectDialog(this);

    // load search widget and hide it
    QUiLoader loader;
    QFile file(":/searchwidget.ui");
    file.open(QFile::ReadOnly);
    search_widget = loader.load(&file, ui->mainOutput);
    Q_ASSERT_X(search_widget, "MainWindow::MainWindow", "error while loading searchwidget.ui");
    file.close();

    search_input = search_widget->findChild<QLineEdit*>("searchInput");

    Q_ASSERT_X(search_input, "MainWindow::MainWindow", "didn't find searchInput");

    // to make widget appear on top of : NOT WORKING
//    search_widget->setWindowFlags(search_widget->windowFlags() | Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint);
//    search_widget->setWindowModality(Qt::WindowModal);
    search_widget->hide();

    // show connection dialog
    connect(ui->connectButton, &QAbstractButton::clicked, connect_dlg, &ConnectDialog::show);

    // handle reception of new data from serial port
    connect(session_mgr, &SessionManager::dataReceived, this, &MainWindow::handleDataReceived);

    // get data formatted for display and show it in output view
    connect(output_mgr, &OutputManager::dataConverted, this, &MainWindow::addDataToView);

    // get data formatted for display and show it in output view
    connect(ui->inputBox, &HistoryComboBox::lineEntered, this, &MainWindow::handleNewInput);

    // clear output manager buffer at session start
    connect(session_mgr, &SessionManager::sessionStarted, output_mgr, &OutputManager::clear);

    // clear output text
    connect(session_mgr, &SessionManager::sessionStarted, ui->mainOutput, &QPlainTextEdit::clear);

    // call openSession when user accepts/closes connection dialog
    connect(connect_dlg, &ConnectDialog::openDeviceClicked, session_mgr, &SessionManager::openSession);

    connect(ui->splitOutputBtn, &QToolButton::clicked, this, &MainWindow::toggleOutputSplitter);

    // additional configuration for bottom output
    ui->bottomOutput->hide();
    ui->bottomOutput->document()->setMaximumBlockCount(MAX_OUTPUT_LINES);
    ui->bottomOutput->viewport()->installEventFilter(this);

    // create the search results highlighter and connect search-related signals/slots
    search_highlighter = new SearchHighlighter(ui->mainOutput->document());

    connect(ui->searchButton, &QToolButton::toggled, this, &MainWindow::showSearchWidget);
    connect(search_input, &QLineEdit::textChanged, search_highlighter, &SearchHighlighter::setSearchString);
    search_input->installEventFilter(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::handleNewInput(QString entry)
{
    // if session is not open, this also keeps user input
    if (session_mgr->isSessionOpen())
    {
        entry.append(LINE_ENDING);
        session_mgr->sendToSerial(entry.toLocal8Bit());
        ui->inputBox->clearEditText();
    }
}

void MainWindow::addDataToView(const QString & textdata)
{
    // problem : QTextEdit interprets a '\r' as a new line, so if a buffer ending
    //           with '\r\n' happens to be cut in the middle, there will be 1 extra
    //           line jump in the QTextEdit. To prevent we remove ending '\r' and
    //           prepend them to the next received buffer

    // flag indicating that the previously received buffer ended with CR
    static bool prev_ends_with_CR = false;

    QString newdata;
    if (prev_ends_with_CR)
    {
        // CR was removed at the previous buffer, so now we prepend it
        newdata.append('\r');
        prev_ends_with_CR = false;
    }

    if (textdata.length() > 0)
    {
        QString::const_iterator end_cit = textdata.cend();
        if (textdata.endsWith('\r'))
        {
            // if buffer ends with CR, we don't copy it
            end_cit--;
            prev_ends_with_CR = true;
        }
        std::copy(textdata.begin(), end_cit, std::back_inserter(newdata));
    }

    // record end cursor position before adding text
    QTextCursor prev_end_cursor(ui->mainOutput->document());
    prev_end_cursor.movePosition(QTextCursor::End);

    if (ui->bottomOutput->isVisible())
    {
        // append text to the top output and stay at current position
        QTextCursor cursor(ui->mainOutput->document());
        cursor.movePosition(QTextCursor::End);
        cursor.insertText(newdata);
    }
    else
    {
        // append text to the top output and scroll down
        ui->mainOutput->moveCursor(QTextCursor::End);
        ui->mainOutput->insertPlainText(newdata);
    }

    // append text to bottom output and scroll
    ui->bottomOutput->moveCursor(QTextCursor::End);
    ui->bottomOutput->insertPlainText(newdata);

//    handleSearchTextChanged(search_input->text());
}

void MainWindow::handleDataReceived(const QByteArray &data)
{
    (*output_mgr) << data;
}

void MainWindow::toggleOutputSplitter()
{
    ui->bottomOutput->setVisible(!ui->bottomOutput->isVisible());
}

bool MainWindow::eventFilter(QObject *target, QEvent *event)
{
    if (event->type() == QEvent::Wheel)
        return true;
    if (event->type() == QEvent::KeyPress)
    {
        QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
        if (keyEvent->key() == Qt::Key_Escape && search_widget->isVisible())
        {
            emit ui->searchButton->toggle();
        }
    }

    // base class behaviour
    return QMainWindow::eventFilter(target, event);
}

void MainWindow::resizeEvent(QResizeEvent *event)
{
    // todo :remove hardcoded values
    search_widget->setGeometry(event->size().width() - search_widget->width() - 40, -2, 300, 40);

    // base class implementations
    QMainWindow::resizeEvent(event);
}

void MainWindow::showSearchWidget(bool show)
{
    QPropertyAnimation *animation = new QPropertyAnimation(search_widget, "geometry");
    animation->setDuration(150);

    QRect showed_pos(this->size().width() - search_widget->width() - 40, -2, 300, 40);
    QRect hidden_pos(this->size().width() - search_widget->width() - 40, -40, 300, 40);

    animation->setStartValue(show ? hidden_pos : showed_pos);
    animation->setEndValue(show ? showed_pos : hidden_pos);

    animation->start();
    search_widget->setVisible(true);
}
<|endoftext|>