<commit_before>
#include <utility>    // std::move
#include <string>     // std::string
#include <iostream>   // std::ostream
#include <memory>     // std::unique_ptr
#include <shark.hpp>

using namespace std;
using namespace shark;

class tester {
	ostream& out;
	string current;
	long fails;
	long tests;
	long curfails;
	long curchecks;

public:
	tester(ostream& out): out(out), fails(0), tests(0) { }
	~tester() { }
	void begin_test(const std::string& name);
	void end_test();
	void add_result(test_result r);
};

void tester::begin_test(const std::string& name) {
	current = name;
	curfails = 0;
	curchecks = 0;
	if(world().procid == 0)
		out << "Begin test " << current << endl;
	world().sync();
}

void tester::end_test() {
	world().sync();
	bool fail = curfails > 0;
	tests++;
	if(fail) fails++;
	if(world().procid == 0) {
		out << "End test " << current << ": ";
		if(!fail)
			out << "Success (" << curchecks << " checks)" << endl;
		else
			out << "FAILED (" << curfails << " of " << curchecks << " checks failed)" << endl;
	}
}

void tester::add_result(test_result r) {
	curchecks += r.checks;
	curfails += r.fails;
}

using namespace shark::ndim;

template<int ndim, typename S>
class suite1 {
	static_assert(S::number_of_dimensions == ndim, "Source dimensionality");

	const Domain<ndim>& dom;
	const S src;
	typedef typename source<S>::element_type T;

	coords_range<ndim> subrange();
	unique_ptr<T[]> src_buf(coords_range<ndim> r);

public:
	suite1(const Domain<ndim>& dom, const S& src): dom(dom), src(src) { }
	~suite1() { }
	void test_basic(tester& t);
	void test_move(tester& t);
	void test_ghost(tester& t);
	void test_ghost_corner(tester& t);
	void test_ghost_periodic(tester& t);
	void test_get(tester& t);
	void test_put(tester& t);
	void test_accumulate(tester& t);
	void test_reshape(tester& t);
	void run(tester& t) {
		test_basic(t);
		test_move(t);
		test_ghost(t);
		test_ghost_corner(t);
		test_ghost_periodic(t);
		test_get(t);
		test_put(t);
		test_accumulate(t);
		test_reshape(t);
	}
};

template<int ndim, typename S>
suite1<ndim,S> make_suite1(const Domain<ndim>& dom, const S& src) {
	return suite1<ndim,S>(dom, src);
}

template<int ndim, typename S>
coords_range<ndim> suite1<ndim,S>::subrange() {
	coords_range<ndim> total = dom.total();
	coords_range<ndim> r;
	for(int d = 0; d < ndim; d++) {
		coord q = (total.upper[d] - total.lower[d])/4;
		r.lower[d] = total.lower[d] + q;
		r.upper[d] = total.lower[d] + q * 3;
	}
	return r;
}

template<int ndim, typename S>
unique_ptr<typename suite1<ndim,S>::T[]> suite1<ndim,S>::src_buf(coords_range<ndim> r) {
	const typename S::accessor s(src);
	coords<ndim+1> ld = r.stride();
	unique_ptr<T[]> ptr(new T[ld[0]]);
	r.for_each([&s,r,ld,&ptr](coords<ndim> ii) {
		ptr[(ii - r.lower).offset(ld)] = s(ii);
	});
	return ptr;
}

template<int ndim, typename S>
void suite1<ndim,S>::test_basic(tester& t) {
	t.begin_test("test_basic");
	{
		GlobalArray<ndim,T> ga(dom);
		ga = src;
		t.add_result(check(ga == src));
	}
	t.end_test();
}

template<int ndim, typename S>
void suite1<ndim,S>::test_move(tester& t) {
	t.begin_test("test_move");
	{
		GlobalArray<ndim,T> ga(dom);
		ga = constant(dom, T());
		{
			GlobalArray<ndim,T> tmp(dom);
			tmp = src;
			ga = std::move(tmp);
		}
		t.add_result(check(ga == src));
	}
	t.end_test();
}

template<int ndim, typename S>
void suite1<ndim,S>::test_ghost(tester& t) {
	t.begin_test("test_ghost");
	coords<ndim> gw;
	for(int d = 0; d < ndim; d++)
		gw[d] = 2;
	coords_range<ndim> inner = dom.total();
	for(int d = 0; d < ndim; d++) {
		inner.lower[d] += gw[d];
		inner.upper[d] -= gw[d];
	}
	{
		GlobalArray<ndim,T> ga(dom, gw);
		ga = src;
		ga.update();
		t.add_result(check(inner, ga == src));
		for(int d = 0; d < ndim; d++) {
			coords<ndim> sd = {{}}, su = {{}};
			sd[d] = -1;
			su[d] = 1;
			t.add_result(check(inner,
				shift(ga,sd) == shift(src,sd) &&
				shift(ga,su) == shift(src,su) &&
				shift(ga,sd+sd) == shift(src,sd+sd) &&
				shift(ga,su+su) == shift(src,su+su)));
		}
	}
	t.end_test();
}

template<int ndim, typename S>
void suite1<ndim,S>::test_ghost_corner(tester& t) {
	t.begin_test("test_ghost_corner");
	coords<ndim> gw;
	for(int d = 0; d < ndim; d++)
		gw[d] = 2;
	coords_range<ndim> inner = dom.total();
	for(int d = 0; d < ndim; d++) {
		inner.lower[d] += gw[d];
		inner.upper[d] -= gw[d];
	}
	{
		GlobalArray<ndim,T> ga(dom, gw, true);
		ga = src;
		ga.update();
		t.add_result(check(inner, ga == src));
		t.add_result(check(inner, shift(ga,gw) == shift(src,gw) && shift(ga,-gw) == shift(src,-gw)));
	}
	t.end_test();
}

template<int ndim, typename S>
void suite1<ndim,S>::test_ghost_periodic(tester& t) {
	t.begin_test("test_ghost_periodic");
	coords<ndim> gw;
	for(int d = 0; d < ndim; d++)
		gw[d] = 2;
	typename GlobalArray<ndim,T>::bounds bd;
	for(int d = 0; d < ndim; d++)
		bd[d] = Boundary<ndim,T>::periodic();
	{
		GlobalArray<ndim,T> ga(dom, gw, false, bd);
		ga = src;
		ga.update();
		t.add_result(check(ga == src));
		for(int d = 0; d < ndim; d++) {
			coords<ndim> sd = {{}}, su = {{}};
			sd[d] = -1;
			su[d] = 1;
			t.add_result(check(
				shift(ga,sd) == shift(src,sd,dom.total()) &&
				shift(ga,su) == shift(src,su,dom.total()) &&
				shift(ga,sd+sd) == shift(src,sd+sd,dom.total()) &&
				shift(ga,su+su) == shift(src,su+su,dom.total())));
		}
	}
	t.end_test();
}

template<int ndim, typename S>
void suite1<ndim,S>::test_get(tester& t) {
	t.begin_test("test_get");
	coords_range<ndim> r = subrange();
	coords<ndim+1> ld = r.stride();
	{
		GlobalArray<ndim,T> ga(dom);
		ga = src;
		// Everyone does a "get" and checks the result
		unique_ptr<T[]> ptr(new T[ld[0]]);
		ga.get(r, ptr.get());
		{
			test_result tr = test_result();
			const typename S::accessor s(src);
			r.for_each([&tr,&s,r,ld,&ptr](coords<ndim> ii) {
				if(s(ii) != ptr[(ii - r.lower).offset(ld)])
					tr.fails++;
				tr.checks++;
			});
			// Add everything together
			t.add_result(dom.group.external_sum(move(tr)));
		}
	}
	t.end_test();
}

template<int ndim, typename S>
void suite1<ndim,S>::test_put(tester& t) {
	t.begin_test("test_put");
	coords_range<ndim> r = subrange();
	{
		GlobalArray<ndim,T> ga(dom);
		ga = constant(dom, T());
		// First one does a put
		dom.group.sync();
		if (dom.group.procid == 0)
			ga.put(r, src_buf(r).get());
		dom.group.sync();
		// Everyone helps check
		t.add_result(check(r, ga == src));
	}
	t.end_test();
}

template<int ndim, typename S>
void suite1<ndim,S>::test_accumulate(tester& t) {
	t.begin_test("test_accumulate");
	coords_range<ndim> r = subrange();
	{
		GlobalArray<ndim,T> ga(dom);
		ga = constant(dom, T());
		// First and last one contribute
		dom.group.sync();
		if (dom.group.procid == 0)
			ga.accumulate(r, src_buf(r).get());
		if (dom.group.procid == dom.group.nprocs-1)
			ga.accumulate(r, src_buf(r).get());
		dom.group.sync();
		// Everyone helps check
		t.add_result(check(r, ga == src+src));
	}
	t.end_test();
}

template<int ndim, typename S>
void suite1<ndim,S>::test_reshape(tester& t) {
	t.begin_test("test_reshape");
	{
		GlobalArray<ndim,T> ga(dom);
		ga = src;
		// Construct distribution where everything is assigned to first one
		typename Domain<ndim>::dists alt_nd(dom.nd);
		for(int d = 0; d < ndim; d++) {
			alt_nd[d][0] = 0;
			for(int p = 1; p <= dom.np[d]; p++)
				alt_nd[d][p] = dom.n[d];
		}
		Domain<ndim> alt_dom(dom.group, dom.n, dom.np, alt_nd);
		ga.reshape(alt_dom);
		const typename GlobalArray<ndim,T>::accessor a(ga);
		const typename S::accessor s(src);
		t.add_result(alt_dom.sum(test_result(), [&a,&s](test_result& tr, coords<ndim> ii) {
			if(s(ii) != a(ii))
				tr.fails++;
			tr.checks++;
		}));
	}
	t.end_test();
}

int main(int argc, char* argv[]) {
	Init(&argc, &argv);
	SetupThreads();
	tester t(cerr);
	if(world().procid == 0)
		cerr << "Testing <1,int>" << endl;
	{
		coords<1> n = {{1000}};
		Domain<1> dom(world(), n);
		auto f = coord_val<0>(dom, 1000);
		make_suite1(dom, f).run(t);
	}
	if(world().procid == 0)
		cerr << endl << "Testing <3,double>" << endl;
	{
		coords<3> n = {{100,100,100}};
		Domain<3> dom(world(), n);
		auto f = sin(coord_val<0>(dom, 2*M_PI, false)) * cos(coord_val<1>(dom, 2*M_PI, false)) * coord_val<2>(dom, 1.0, false);
		make_suite1(dom, f).run(t);
	}
	if(world().procid == 0)
		cerr << endl << "Testing <3,vec<3,double>>" << endl;
	{
		coords<3> n = {{100,100,100}};
		Domain<3> dom(world(), n);
		const vec<3,double> one = {{1.0, 1.0, 1.0}};
		const vec<3,double> mid = {{0.5, 0.5, 0.5}};
		auto f = abs(coord_vec(dom, one) - mid);
		make_suite1(dom, f).run(t);
	}
	Finalize();
}
<commit_msg>Reshape test<commit_after>
#include <utility>    // std::move
#include <string>     // std::string
#include <iostream>   // std::ostream
#include <memory>     // std::unique_ptr
#include <shark.hpp>

using namespace std;
using namespace shark;

class tester {
	ostream& out;
	string current;
	long fails;
	long tests;
	long curfails;
	long curchecks;

public:
	tester(ostream& out): out(out), fails(0), tests(0) { }
	~tester() { }
	void begin_test(const std::string& name);
	void end_test();
	void add_result(test_result r);
};

void tester::begin_test(const std::string& name) {
	current = name;
	curfails = 0;
	curchecks = 0;
	if(world().procid == 0)
		out << "Begin test " << current << endl;
	world().sync();
}

void tester::end_test() {
	world().sync();
	bool fail = curfails > 0;
	tests++;
	if(fail) fails++;
	if(world().procid == 0) {
		out << "End test " << current << ": ";
		if(!fail)
			out << "Success (" << curchecks << " checks)" << endl;
		else
			out << "FAILED (" << curfails << " of " << curchecks << " checks failed)" << endl;
	}
}

void tester::add_result(test_result r) {
	curchecks += r.checks;
	curfails += r.fails;
}

using namespace shark::ndim;

template<int ndim, typename S>
class suite1 {
	static_assert(S::number_of_dimensions == ndim, "Source dimensionality");

	const Domain<ndim>& dom;
	const S src;
	typedef typename source<S>::element_type T;

	coords_range<ndim> subrange();
	unique_ptr<T[]> src_buf(coords_range<ndim> r);

	void test_reshape_domain(tester& t, const Domain<ndim>& alt_dom);

public:
	suite1(const Domain<ndim>& dom, const S& src): dom(dom), src(src) { }
	~suite1() { }
	void test_basic(tester& t);
	void test_move(tester& t);
	void test_ghost(tester& t);
	void test_ghost_corner(tester& t);
	void test_ghost_periodic(tester& t);
	void test_get(tester& t);
	void test_put(tester& t);
	void test_accumulate(tester& t);
	void test_reshape(tester& t);
	void run(tester& t) {
		test_basic(t);
		test_move(t);
		test_ghost(t);
		test_ghost_corner(t);
		test_ghost_periodic(t);
		test_get(t);
		test_put(t);
		test_accumulate(t);
		test_reshape(t);
	}
};

template<int ndim, typename S>
suite1<ndim,S> make_suite1(const Domain<ndim>& dom, const S& src) {
	return suite1<ndim,S>(dom, src);
}

template<int ndim, typename S>
coords_range<ndim> suite1<ndim,S>::subrange() {
	coords_range<ndim> total = dom.total();
	coords_range<ndim> r;
	for(int d = 0; d < ndim; d++) {
		coord q = (total.upper[d] - total.lower[d])/4;
		r.lower[d] = total.lower[d] + q;
		r.upper[d] = total.lower[d] + q * 3;
	}
	return r;
}

template<int ndim, typename S>
unique_ptr<typename suite1<ndim,S>::T[]> suite1<ndim,S>::src_buf(coords_range<ndim> r) {
	const typename S::accessor s(src);
	coords<ndim+1> ld = r.stride();
	unique_ptr<T[]> ptr(new T[ld[0]]);
	r.for_each([&s,r,ld,&ptr](coords<ndim> ii) {
		ptr[(ii - r.lower).offset(ld)] = s(ii);
	});
	return ptr;
}

template<int ndim, typename S>
void suite1<ndim,S>::test_basic(tester& t) {
	t.begin_test("test_basic");
	{
		GlobalArray<ndim,T> ga(dom);
		ga = src;
		t.add_result(check(ga == src));
	}
	t.end_test();
}

template<int ndim, typename S>
void suite1<ndim,S>::test_move(tester& t) {
	t.begin_test("test_move");
	{
		GlobalArray<ndim,T> ga(dom);
		ga = constant(dom, T());
		{
			GlobalArray<ndim,T> tmp(dom);
			tmp = src;
			ga = std::move(tmp);
		}
		t.add_result(check(ga == src));
	}
	t.end_test();
}

template<int ndim, typename S>
void suite1<ndim,S>::test_ghost(tester& t) {
	t.begin_test("test_ghost");
	coords<ndim> gw;
	for(int d = 0; d < ndim; d++)
		gw[d] = 2;
	coords_range<ndim> inner = dom.total();
	for(int d = 0; d < ndim; d++) {
		inner.lower[d] += gw[d];
		inner.upper[d] -= gw[d];
	}
	{
		GlobalArray<ndim,T> ga(dom, gw);
		ga = src;
		ga.update();
		t.add_result(check(inner, ga == src));
		for(int d = 0; d < ndim; d++) {
			coords<ndim> sd = {{}}, su = {{}};
			sd[d] = -1;
			su[d] = 1;
			t.add_result(check(inner,
				shift(ga,sd) == shift(src,sd) &&
				shift(ga,su) == shift(src,su) &&
				shift(ga,sd+sd) == shift(src,sd+sd) &&
				shift(ga,su+su) == shift(src,su+su)));
		}
	}
	t.end_test();
}

template<int ndim, typename S>
void suite1<ndim,S>::test_ghost_corner(tester& t) {
	t.begin_test("test_ghost_corner");
	coords<ndim> gw;
	for(int d = 0; d < ndim; d++)
		gw[d] = 2;
	coords_range<ndim> inner = dom.total();
	for(int d = 0; d < ndim; d++) {
		inner.lower[d] += gw[d];
		inner.upper[d] -= gw[d];
	}
	{
		GlobalArray<ndim,T> ga(dom, gw, true);
		ga = src;
		ga.update();
		t.add_result(check(inner, ga == src));
		t.add_result(check(inner, shift(ga,gw) == shift(src,gw) && shift(ga,-gw) == shift(src,-gw)));
	}
	t.end_test();
}

template<int ndim, typename S>
void suite1<ndim,S>::test_ghost_periodic(tester& t) {
	t.begin_test("test_ghost_periodic");
	coords<ndim> gw;
	for(int d = 0; d < ndim; d++)
		gw[d] = 2;
	typename GlobalArray<ndim,T>::bounds bd;
	for(int d = 0; d < ndim; d++)
		bd[d] = Boundary<ndim,T>::periodic();
	{
		GlobalArray<ndim,T> ga(dom, gw, false, bd);
		ga = src;
		ga.update();
		t.add_result(check(ga == src));
		for(int d = 0; d < ndim; d++) {
			coords<ndim> sd = {{}}, su = {{}};
			sd[d] = -1;
			su[d] = 1;
			t.add_result(check(
				shift(ga,sd) == shift(src,sd,dom.total()) &&
				shift(ga,su) == shift(src,su,dom.total()) &&
				shift(ga,sd+sd) == shift(src,sd+sd,dom.total()) &&
				shift(ga,su+su) == shift(src,su+su,dom.total())));
		}
	}
	t.end_test();
}

template<int ndim, typename S>
void suite1<ndim,S>::test_get(tester& t) {
	t.begin_test("test_get");
	coords_range<ndim> r = subrange();
	coords<ndim+1> ld = r.stride();
	{
		GlobalArray<ndim,T> ga(dom);
		ga = src;
		// Everyone does a "get" and checks the result
		unique_ptr<T[]> ptr(new T[ld[0]]);
		ga.get(r, ptr.get());
		{
			test_result tr = test_result();
			const typename S::accessor s(src);
			r.for_each([&tr,&s,r,ld,&ptr](coords<ndim> ii) {
				if(s(ii) != ptr[(ii - r.lower).offset(ld)])
					tr.fails++;
				tr.checks++;
			});
			// Add everything together
			t.add_result(dom.group.external_sum(move(tr)));
		}
	}
	t.end_test();
}

template<int ndim, typename S>
void suite1<ndim,S>::test_put(tester& t) {
	t.begin_test("test_put");
	coords_range<ndim> r = subrange();
	{
		GlobalArray<ndim,T> ga(dom);
		ga = constant(dom, T());
		// First one does a put
		dom.group.sync();
		if (dom.group.procid == 0)
			ga.put(r, src_buf(r).get());
		dom.group.sync();
		// Everyone helps check
		t.add_result(check(r, ga == src));
	}
	t.end_test();
}

template<int ndim, typename S>
void suite1<ndim,S>::test_accumulate(tester& t) {
	t.begin_test("test_accumulate");
	coords_range<ndim> r = subrange();
	{
		GlobalArray<ndim,T> ga(dom);
		ga = constant(dom, T());
		// First and last one contribute
		dom.group.sync();
		if (dom.group.procid == 0)
			ga.accumulate(r, src_buf(r).get());
		if (dom.group.procid == dom.group.nprocs-1)
			ga.accumulate(r, src_buf(r).get());
		dom.group.sync();
		// Everyone helps check
		t.add_result(check(r, ga == src+src));
	}
	t.end_test();
}

template<int ndim, typename S>
void suite1<ndim,S>::test_reshape_domain(tester& t, const Domain<ndim>& alt_dom) {
	GlobalArray<ndim,T> ga(dom);
	ga = src;
	ga.reshape(alt_dom);
	const typename GlobalArray<ndim,T>::accessor a(ga);
	const typename S::accessor s(src);
	t.add_result(alt_dom.sum(test_result(), [&a,&s](test_result& tr, coords<ndim> ii) {
		if(s(ii) != a(ii))
			tr.fails++;
		tr.checks++;
	}));
}

template<int ndim, typename S>
void suite1<ndim,S>::test_reshape(tester& t) {
	t.begin_test("test_reshape");
	{
		typename Domain<ndim>::pcoords row_np;
		row_np[0] = dom.group.nprocs;
		for(int d = 1; d < ndim; d++)
			row_np[d] = 1;
		test_reshape_domain(t, Domain<ndim>(dom.group, dom.n, row_np));
		typename Domain<ndim>::pcoords col_np;
		for(int d = 0; d < ndim-1; d++)
			col_np[d] = 1;
		col_np[ndim-1] = dom.group.nprocs;
		test_reshape_domain(t, Domain<ndim>(dom.group, dom.n, col_np));
	}
	t.end_test();
}

int main(int argc, char* argv[]) {
	Init(&argc, &argv);
	SetupThreads();
	tester t(cerr);
	if(world().procid == 0)
		cerr << "Testing <1,int>" << endl;
	{
		coords<1> n = {{1000}};
		Domain<1> dom(world(), n);
		auto f = coord_val<0>(dom, 1000);
		make_suite1(dom, f).run(t);
	}
	if(world().procid == 0)
		cerr << endl << "Testing <3,double>" << endl;
	{
		coords<3> n = {{100,100,100}};
		Domain<3> dom(world(), n);
		auto f = sin(coord_val<0>(dom, 2*M_PI, false)) * cos(coord_val<1>(dom, 2*M_PI, false)) * coord_val<2>(dom, 1.0, false);
		make_suite1(dom, f).run(t);
	}
	if(world().procid == 0)
		cerr << endl << "Testing <3,vec<3,double>>" << endl;
	{
		coords<3> n = {{100,100,100}};
		Domain<3> dom(world(), n);
		const vec<3,double> one = {{1.0, 1.0, 1.0}};
		const vec<3,double> mid = {{0.5, 0.5, 0.5}};
		auto f = abs(coord_vec(dom, one) - mid);
		make_suite1(dom, f).run(t);
	}
	Finalize();
}
<|endoftext|>


<commit_before>// Copyright 2014 Alessio Sclocco <a.sclocco@vu.nl>
//
// 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.

#include <iostream>
#include <string>
#include <vector>
#include <exception>
#include <fstream>
#include <iomanip>
#include <limits>

#include <ArgumentList.hpp>
#include <Observation.hpp>
#include <InitializeOpenCL.hpp>
#include <Kernel.hpp>
#include <Shifts.hpp>
#include <Dedispersion.hpp>
#include <utils.hpp>
#include <Timer.hpp>
#include <Stats.hpp>

typedef float dataType;
std::string typeName("float");

void initializeDeviceMemory(cl::Context & clContext, cl::CommandQueue * clQueue, std::vector< float > * shifts, cl::Buffer * shifts_d, const unsigned int shifts_size, cl::Buffer * dispersedData_d, const unsigned int dispersedData_size, cl::Buffer * dedispersedData_d, const unsigned int dedispersedData_size);

int main(int argc, char * argv[]) {
  bool localMem = false;
  bool reInit = false;
	unsigned int nrIterations = 0;
	unsigned int clPlatformID = 0;
	unsigned int clDeviceID = 0;
	unsigned int minThreads = 0;
  unsigned int maxThreads = 0;
	unsigned int maxRows = 0;
	unsigned int maxColumns = 0;
  unsigned int threadUnit = 0;
  unsigned int threadIncrement = 0;
  unsigned int maxItems = 0;
  unsigned int maxUnroll = 0;
  unsigned int maxLoopBodySize = 0;
  AstroData::Observation observation;
  cl::Event event;

	try {
    isa::utils::ArgumentList args(argc, argv);

		nrIterations = args.getSwitchArgument< unsigned int >("-iterations");
		clPlatformID = args.getSwitchArgument< unsigned int >("-opencl_platform");
		clDeviceID = args.getSwitchArgument< unsigned int >("-opencl_device");
    localMem = args.getSwitch("-local");
		observation.setPadding(args.getSwitchArgument< unsigned int >("-padding"));
    threadUnit = args.getSwitchArgument< unsigned int >("-thread_unit");
		minThreads = args.getSwitchArgument< unsigned int >("-min_threads");
		maxThreads = args.getSwitchArgument< unsigned int >("-max_threads");
		maxRows = args.getSwitchArgument< unsigned int >("-max_rows");
		maxColumns = args.getSwitchArgument< unsigned int >("-max_columns");
    threadIncrement = args.getSwitchArgument< unsigned int >("-thread_increment");
		maxItems = args.getSwitchArgument< unsigned int >("-max_items");
    maxUnroll = args.getSwitchArgument< unsigned int >("-max_unroll");
    maxLoopBodySize = args.getSwitchArgument< unsigned int >("-max_loopsize");
    observation.setFrequencyRange(args.getSwitchArgument< unsigned int >("-channels"), args.getSwitchArgument< float >("-min_freq"), args.getSwitchArgument< float >("-channel_bandwidth"));
		observation.setNrSamplesPerSecond(args.getSwitchArgument< unsigned int >("-samples"));
    observation.setDMRange(args.getSwitchArgument< unsigned int >("-dms"), args.getSwitchArgument< float >("-dm_first"), args.getSwitchArgument< float >("-dm_step"));
	} catch ( isa::utils::EmptyCommandLine & err ) {
		std::cerr << argv[0] << " -iterations ... -opencl_platform ... -opencl_device ... [-local] -padding ... -thread_unit ... -min_threads ... -max_threads ... -max_items ... -max_unroll ... -max_loopsize ... -max_columns ... -max_rows ... -thread_increment ... -min_freq ... -channel_bandwidth ... -samples ... -channels ... -dms ... -dm_first ... -dm_step ..." << std::endl;
		return 1;
	} catch ( std::exception & err ) {
		std::cerr << err.what() << std::endl;
		return 1;
	}

  // Allocate host memory
  std::vector< float > * shifts = PulsarSearch::getShifts(observation);
  observation.setNrSamplesPerDispersedChannel(observation.getNrSamplesPerSecond() + static_cast< unsigned int >(shifts->at(0) * (observation.getFirstDM() + ((observation.getNrDMs() - 1) * observation.getDMStep()))));

	// Initialize OpenCL
	cl::Context clContext;
	std::vector< cl::Platform > * clPlatforms = new std::vector< cl::Platform >();
	std::vector< cl::Device > * clDevices = new std::vector< cl::Device >();
	std::vector< std::vector< cl::CommandQueue > > * clQueues = new std::vector< std::vector < cl::CommandQueue > >();
  isa::OpenCL::initializeOpenCL(clPlatformID, 1, clPlatforms, &clContext, clDevices, clQueues);

	// Allocate device memory
  cl::Buffer shifts_d;
  cl::Buffer dispersedData_d;
  cl::Buffer dedispersedData_d;

  try {
  initializeDeviceMemory(clContext, &(clQueues->at(clDeviceID)[0]), shifts, &shifts_d, shifts->size(), &dispersedData_d, observation.getNrChannels() * observation.getNrSamplesPerDispersedChannel(), &dedispersedData_d, observation.getNrDMs() * observation.getNrSamplesPerPaddedSecond());
  } catch ( cl::Error & err ) {
    return -1;
  }

	// Find the parameters
	std::vector< unsigned int > samplesPerBlock;
	for ( unsigned int samples = minThreads; samples <= maxColumns; samples += threadIncrement ) {
		if ( (observation.getNrSamplesPerPaddedSecond() % samples) == 0 ) {
			samplesPerBlock.push_back(samples);
		}
	}
	std::vector< unsigned int > DMsPerBlock;
	for ( unsigned int DMs = 1; DMs <= maxRows; DMs++ ) {
		if ( (observation.getNrDMs() % DMs) == 0 ) {
			DMsPerBlock.push_back(DMs);
		}
	}

	std::cout << std::fixed << std::endl;
	std::cout << "# nrDMs nrChannels nrSamples local samplesPerBlock DMsPerBlock samplesPerThread DMsPerThread unroll GFLOP/s GB/s time stdDeviation COV" << std::endl << std::endl;

	for ( std::vector< unsigned int >::iterator samples = samplesPerBlock.begin(); samples != samplesPerBlock.end(); ++samples ) {
		for ( std::vector< unsigned int >::iterator DMs = DMsPerBlock.begin(); DMs != DMsPerBlock.end(); ++DMs ) {
			if ( ((*samples) * (*DMs)) > maxThreads ) {
				break;
			} else if ( ((*samples) * (*DMs)) % threadUnit != 0 ) {
        continue;
      }

			for ( unsigned int samplesPerThread = 1; samplesPerThread <= maxItems; samplesPerThread++ ) {
				if ( (observation.getNrSamplesPerPaddedSecond() % ((*samples) * samplesPerThread)) != 0 ) {
					continue;
				}

				for ( unsigned int DMsPerThread = 1; DMsPerThread <= maxItems; DMsPerThread++ ) {
					if ( (observation.getNrDMs() % ((*DMs) * DMsPerThread)) != 0 ) {
						continue;
					} else if ( (samplesPerThread * DMsPerThread) + DMsPerThread > maxItems ) {
						break;
					}

          for ( unsigned int unroll = 1; unroll <= maxUnroll; unroll++ ) {
            if ( (observation.getNrChannels() - 1) % unroll != 0 ) {
              continue;
            } else if ( (samplesPerThread * DMsPerThread * unroll) > maxLoopBodySize ) {
              break;
            }
            // Generate kernel
            double gflops = isa::utils::giga(static_cast< long long unsigned int >(observation.getNrDMs()) * observation.getNrChannels() * observation.getNrSamplesPerSecond());
            double gbs = isa::utils::giga(((static_cast< long long unsigned int >(observation.getNrDMs()) * observation.getNrSamplesPerSecond() * (observation.getNrChannels() + 1)) * sizeof(dataType)) + ((observation.getNrDMs() * observation.getNrChannels()) * sizeof(unsigned int)));
            isa::utils::Timer timer;
            cl::Kernel * kernel;
            std::string * code = PulsarSearch::getDedispersionOpenCL(localMem, *samples, *DMs, samplesPerThread, DMsPerThread, unroll, typeName, observation, *shifts);

            if ( reInit ) {
              delete clQueues;
              clQueues = new std::vector< std::vector < cl::CommandQueue > >();
              isa::OpenCL::initializeOpenCL(clPlatformID, 1, clPlatforms, &clContext, clDevices, clQueues);
              try {
                initializeDeviceMemory(clContext, &(clQueues->at(clDeviceID)[0]), shifts, &shifts_d, shifts->size(), &dispersedData_d, observation.getNrChannels() * observation.getNrSamplesPerDispersedChannel(), &dedispersedData_d, observation.getNrDMs() * observation.getNrSamplesPerPaddedSecond());
              } catch ( cl::Error & err ) {
                return -1;
              }
              reInit = false;
            }
            try {
              kernel = isa::OpenCL::compile("dedispersion", *code, "-cl-mad-enable -Werror", clContext, clDevices->at(clDeviceID));
            } catch ( isa::OpenCL::OpenCLError & err ) {
              std::cerr << err.what() << std::endl;
              delete code;
              break;
            }
            delete code;

            cl::NDRange global(observation.getNrSamplesPerSecond() / samplesPerThread, observation.getNrDMs() / DMsPerThread);
            cl::NDRange local(*samples, *DMs);

            kernel->setArg(0, dispersedData_d);
            kernel->setArg(1, dedispersedData_d);
            kernel->setArg(2, shifts_d);

            try {
              // Warm-up run
              clQueues->at(clDeviceID)[0].finish();
              clQueues->at(clDeviceID)[0].enqueueNDRangeKernel(*kernel, cl::NullRange, global, local, 0, &event);
              event.wait();
              // Tuning runs
              for ( unsigned int iteration = 0; iteration < nrIterations; iteration++ ) {
                timer.start();
                clQueues->at(clDeviceID)[0].enqueueNDRangeKernel(*kernel, cl::NullRange, global, local, 0, &event);
                event.wait();
                timer.stop();
              }
            } catch ( cl::Error & err ) {
              std::cerr << "OpenCL error kernel execution (";
              std::cerr << localMem << ", " << *samples << ", " << *DMs << ", " << samplesPerThread << ", " << DMsPerThread << ", " << unroll << "): ";
              std::cerr << isa::utils::toString(err.err()) << "." << std::endl;
              delete kernel;
              if ( err.err() == -4 || err.err() == -61 ) {
                return -1;
              }
              reInit = true;
              break;
            }
            delete kernel;

            std::cout << observation.getNrDMs() << " " << observation.getNrChannels() << " " << observation.getNrSamplesPerSecond() << " " << localMem << " " << *samples << " " << *DMs << " " << samplesPerThread << " " << DMsPerThread << " " << unroll << " ";
            std::cout << std::setprecision(3);
            std::cout << gflops / timer.getAverageTime() << " ";
            std::cout << gbs / timer.getAverageTime() << " ";
            std::cout << std::setprecision(6);
            std::cout << timer.getAverageTime() << " " << timer.getStandardDeviation() << " ";
            std::cout << timer.getCoefficientOfVariation() <<  std::endl;
          }
				}
			}
		}
	}

	std::cout << std::endl;

	return 0;
}

void initializeDeviceMemory(cl::Context & clContext, cl::CommandQueue * clQueue, std::vector< float > * shifts, cl::Buffer * shifts_d, const unsigned int shifts_size, cl::Buffer * dispersedData_d, const unsigned int dispersedData_size, cl::Buffer * dedispersedData_d, const unsigned int dedispersedData_size) {
  try {
    *shifts_d = cl::Buffer(clContext, CL_MEM_READ_ONLY, shifts_size * sizeof(float), 0, 0);
    *dispersedData_d = cl::Buffer(clContext, CL_MEM_READ_ONLY, dispersedData_size * sizeof(dataType), 0, 0);
    *dedispersedData_d = cl::Buffer(clContext, CL_MEM_READ_WRITE, dedispersedData_size * sizeof(dataType), 0, 0);
    clQueue->enqueueWriteBuffer(*shifts_d, CL_FALSE, 0, shifts_size * sizeof(float), reinterpret_cast< void * >(shifts->data()));
  } catch ( cl::Error & err ) {
    std::cerr << "OpenCL error: " << isa::utils::toString(err.err()) << "." << std::endl;
    throw;
  }
}

<commit_msg>Sync the device during memory transfers.<commit_after>// Copyright 2014 Alessio Sclocco <a.sclocco@vu.nl>
//
// 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.

#include <iostream>
#include <string>
#include <vector>
#include <exception>
#include <fstream>
#include <iomanip>
#include <limits>

#include <ArgumentList.hpp>
#include <Observation.hpp>
#include <InitializeOpenCL.hpp>
#include <Kernel.hpp>
#include <Shifts.hpp>
#include <Dedispersion.hpp>
#include <utils.hpp>
#include <Timer.hpp>
#include <Stats.hpp>

typedef float dataType;
std::string typeName("float");

void initializeDeviceMemory(cl::Context & clContext, cl::CommandQueue * clQueue, std::vector< float > * shifts, cl::Buffer * shifts_d, const unsigned int shifts_size, cl::Buffer * dispersedData_d, const unsigned int dispersedData_size, cl::Buffer * dedispersedData_d, const unsigned int dedispersedData_size);

int main(int argc, char * argv[]) {
  bool localMem = false;
  bool reInit = false;
	unsigned int nrIterations = 0;
	unsigned int clPlatformID = 0;
	unsigned int clDeviceID = 0;
	unsigned int minThreads = 0;
  unsigned int maxThreads = 0;
	unsigned int maxRows = 0;
	unsigned int maxColumns = 0;
  unsigned int threadUnit = 0;
  unsigned int threadIncrement = 0;
  unsigned int maxItems = 0;
  unsigned int maxUnroll = 0;
  unsigned int maxLoopBodySize = 0;
  AstroData::Observation observation;
  cl::Event event;

	try {
    isa::utils::ArgumentList args(argc, argv);

		nrIterations = args.getSwitchArgument< unsigned int >("-iterations");
		clPlatformID = args.getSwitchArgument< unsigned int >("-opencl_platform");
		clDeviceID = args.getSwitchArgument< unsigned int >("-opencl_device");
    localMem = args.getSwitch("-local");
		observation.setPadding(args.getSwitchArgument< unsigned int >("-padding"));
    threadUnit = args.getSwitchArgument< unsigned int >("-thread_unit");
		minThreads = args.getSwitchArgument< unsigned int >("-min_threads");
		maxThreads = args.getSwitchArgument< unsigned int >("-max_threads");
		maxRows = args.getSwitchArgument< unsigned int >("-max_rows");
		maxColumns = args.getSwitchArgument< unsigned int >("-max_columns");
    threadIncrement = args.getSwitchArgument< unsigned int >("-thread_increment");
		maxItems = args.getSwitchArgument< unsigned int >("-max_items");
    maxUnroll = args.getSwitchArgument< unsigned int >("-max_unroll");
    maxLoopBodySize = args.getSwitchArgument< unsigned int >("-max_loopsize");
    observation.setFrequencyRange(args.getSwitchArgument< unsigned int >("-channels"), args.getSwitchArgument< float >("-min_freq"), args.getSwitchArgument< float >("-channel_bandwidth"));
		observation.setNrSamplesPerSecond(args.getSwitchArgument< unsigned int >("-samples"));
    observation.setDMRange(args.getSwitchArgument< unsigned int >("-dms"), args.getSwitchArgument< float >("-dm_first"), args.getSwitchArgument< float >("-dm_step"));
	} catch ( isa::utils::EmptyCommandLine & err ) {
		std::cerr << argv[0] << " -iterations ... -opencl_platform ... -opencl_device ... [-local] -padding ... -thread_unit ... -min_threads ... -max_threads ... -max_items ... -max_unroll ... -max_loopsize ... -max_columns ... -max_rows ... -thread_increment ... -min_freq ... -channel_bandwidth ... -samples ... -channels ... -dms ... -dm_first ... -dm_step ..." << std::endl;
		return 1;
	} catch ( std::exception & err ) {
		std::cerr << err.what() << std::endl;
		return 1;
	}

  // Allocate host memory
  std::vector< float > * shifts = PulsarSearch::getShifts(observation);
  observation.setNrSamplesPerDispersedChannel(observation.getNrSamplesPerSecond() + static_cast< unsigned int >(shifts->at(0) * (observation.getFirstDM() + ((observation.getNrDMs() - 1) * observation.getDMStep()))));

	// Initialize OpenCL
	cl::Context clContext;
	std::vector< cl::Platform > * clPlatforms = new std::vector< cl::Platform >();
	std::vector< cl::Device > * clDevices = new std::vector< cl::Device >();
	std::vector< std::vector< cl::CommandQueue > > * clQueues = new std::vector< std::vector < cl::CommandQueue > >();
  isa::OpenCL::initializeOpenCL(clPlatformID, 1, clPlatforms, &clContext, clDevices, clQueues);

	// Allocate device memory
  cl::Buffer shifts_d;
  cl::Buffer dispersedData_d;
  cl::Buffer dedispersedData_d;

  try {
  initializeDeviceMemory(clContext, &(clQueues->at(clDeviceID)[0]), shifts, &shifts_d, shifts->size(), &dispersedData_d, observation.getNrChannels() * observation.getNrSamplesPerDispersedChannel(), &dedispersedData_d, observation.getNrDMs() * observation.getNrSamplesPerPaddedSecond());
  } catch ( cl::Error & err ) {
    return -1;
  }

	// Find the parameters
	std::vector< unsigned int > samplesPerBlock;
	for ( unsigned int samples = minThreads; samples <= maxColumns; samples += threadIncrement ) {
		if ( (observation.getNrSamplesPerPaddedSecond() % samples) == 0 ) {
			samplesPerBlock.push_back(samples);
		}
	}
	std::vector< unsigned int > DMsPerBlock;
	for ( unsigned int DMs = 1; DMs <= maxRows; DMs++ ) {
		if ( (observation.getNrDMs() % DMs) == 0 ) {
			DMsPerBlock.push_back(DMs);
		}
	}

	std::cout << std::fixed << std::endl;
	std::cout << "# nrDMs nrChannels nrSamples local samplesPerBlock DMsPerBlock samplesPerThread DMsPerThread unroll GFLOP/s GB/s time stdDeviation COV" << std::endl << std::endl;

	for ( std::vector< unsigned int >::iterator samples = samplesPerBlock.begin(); samples != samplesPerBlock.end(); ++samples ) {
		for ( std::vector< unsigned int >::iterator DMs = DMsPerBlock.begin(); DMs != DMsPerBlock.end(); ++DMs ) {
			if ( ((*samples) * (*DMs)) > maxThreads ) {
				break;
			} else if ( ((*samples) * (*DMs)) % threadUnit != 0 ) {
        continue;
      }

			for ( unsigned int samplesPerThread = 1; samplesPerThread <= maxItems; samplesPerThread++ ) {
				if ( (observation.getNrSamplesPerPaddedSecond() % ((*samples) * samplesPerThread)) != 0 ) {
					continue;
				}

				for ( unsigned int DMsPerThread = 1; DMsPerThread <= maxItems; DMsPerThread++ ) {
					if ( (observation.getNrDMs() % ((*DMs) * DMsPerThread)) != 0 ) {
						continue;
					} else if ( (samplesPerThread * DMsPerThread) + DMsPerThread > maxItems ) {
						break;
					}

          for ( unsigned int unroll = 1; unroll <= maxUnroll; unroll++ ) {
            if ( (observation.getNrChannels() - 1) % unroll != 0 ) {
              continue;
            } else if ( (samplesPerThread * DMsPerThread * unroll) > maxLoopBodySize ) {
              break;
            }
            // Generate kernel
            double gflops = isa::utils::giga(static_cast< long long unsigned int >(observation.getNrDMs()) * observation.getNrChannels() * observation.getNrSamplesPerSecond());
            double gbs = isa::utils::giga(((static_cast< long long unsigned int >(observation.getNrDMs()) * observation.getNrSamplesPerSecond() * (observation.getNrChannels() + 1)) * sizeof(dataType)) + ((observation.getNrDMs() * observation.getNrChannels()) * sizeof(unsigned int)));
            isa::utils::Timer timer;
            cl::Kernel * kernel;
            std::string * code = PulsarSearch::getDedispersionOpenCL(localMem, *samples, *DMs, samplesPerThread, DMsPerThread, unroll, typeName, observation, *shifts);

            if ( reInit ) {
              delete clQueues;
              clQueues = new std::vector< std::vector < cl::CommandQueue > >();
              isa::OpenCL::initializeOpenCL(clPlatformID, 1, clPlatforms, &clContext, clDevices, clQueues);
              try {
                initializeDeviceMemory(clContext, &(clQueues->at(clDeviceID)[0]), shifts, &shifts_d, shifts->size(), &dispersedData_d, observation.getNrChannels() * observation.getNrSamplesPerDispersedChannel(), &dedispersedData_d, observation.getNrDMs() * observation.getNrSamplesPerPaddedSecond());
              } catch ( cl::Error & err ) {
                return -1;
              }
              reInit = false;
            }
            try {
              kernel = isa::OpenCL::compile("dedispersion", *code, "-cl-mad-enable -Werror", clContext, clDevices->at(clDeviceID));
            } catch ( isa::OpenCL::OpenCLError & err ) {
              std::cerr << err.what() << std::endl;
              delete code;
              break;
            }
            delete code;

            cl::NDRange global(observation.getNrSamplesPerSecond() / samplesPerThread, observation.getNrDMs() / DMsPerThread);
            cl::NDRange local(*samples, *DMs);

            kernel->setArg(0, dispersedData_d);
            kernel->setArg(1, dedispersedData_d);
            kernel->setArg(2, shifts_d);

            try {
              // Warm-up run
              clQueues->at(clDeviceID)[0].finish();
              clQueues->at(clDeviceID)[0].enqueueNDRangeKernel(*kernel, cl::NullRange, global, local, 0, &event);
              event.wait();
              // Tuning runs
              for ( unsigned int iteration = 0; iteration < nrIterations; iteration++ ) {
                timer.start();
                clQueues->at(clDeviceID)[0].enqueueNDRangeKernel(*kernel, cl::NullRange, global, local, 0, &event);
                event.wait();
                timer.stop();
              }
            } catch ( cl::Error & err ) {
              std::cerr << "OpenCL error kernel execution (";
              std::cerr << localMem << ", " << *samples << ", " << *DMs << ", " << samplesPerThread << ", " << DMsPerThread << ", " << unroll << "): ";
              std::cerr << isa::utils::toString(err.err()) << "." << std::endl;
              delete kernel;
              if ( err.err() == -4 || err.err() == -61 ) {
                return -1;
              }
              reInit = true;
              break;
            }
            delete kernel;

            std::cout << observation.getNrDMs() << " " << observation.getNrChannels() << " " << observation.getNrSamplesPerSecond() << " " << localMem << " " << *samples << " " << *DMs << " " << samplesPerThread << " " << DMsPerThread << " " << unroll << " ";
            std::cout << std::setprecision(3);
            std::cout << gflops / timer.getAverageTime() << " ";
            std::cout << gbs / timer.getAverageTime() << " ";
            std::cout << std::setprecision(6);
            std::cout << timer.getAverageTime() << " " << timer.getStandardDeviation() << " ";
            std::cout << timer.getCoefficientOfVariation() <<  std::endl;
          }
				}
			}
		}
	}

	std::cout << std::endl;

	return 0;
}

void initializeDeviceMemory(cl::Context & clContext, cl::CommandQueue * clQueue, std::vector< float > * shifts, cl::Buffer * shifts_d, const unsigned int shifts_size, cl::Buffer * dispersedData_d, const unsigned int dispersedData_size, cl::Buffer * dedispersedData_d, const unsigned int dedispersedData_size) {
  try {
    *shifts_d = cl::Buffer(clContext, CL_MEM_READ_ONLY, shifts_size * sizeof(float), 0, 0);
    *dispersedData_d = cl::Buffer(clContext, CL_MEM_READ_ONLY, dispersedData_size * sizeof(dataType), 0, 0);
    *dedispersedData_d = cl::Buffer(clContext, CL_MEM_READ_WRITE, dedispersedData_size * sizeof(dataType), 0, 0);
    clQueue->enqueueWriteBuffer(*shifts_d, CL_FALSE, 0, shifts_size * sizeof(float), reinterpret_cast< void * >(shifts->data()));
    clQueue->finish();
  } catch ( cl::Error & err ) {
    std::cerr << "OpenCL error: " << isa::utils::toString(err.err()) << "." << std::endl;
    throw;
  }
}

<|endoftext|>


<commit_before>#include "openqpritz.h"

// コンストラクタ(sentenceの場合) / Constructor
OpenQpritz::OpenQpritz(const QString sentence, const int spritzWpmNumber)
{
    m_wordList = makeWordList(sentence);
    m_spritzWpmNumber = spritzWpmNumber;

    spritzLoopNumber = 0;
    m_timer = new QTimer();
}

// コンストラクタ(wordListの場合) / Constructor
OpenQpritz::OpenQpritz(const QStringList wordList, const int spritzWpmNumber)
{
    m_wordList = wordList;
    m_spritzWpmNumber = spritzWpmNumber;

    spritzLoopNumber = 0;
    m_timer = new QTimer();
}

// 文章を単語リストに加工 / make wordList from sentence
QStringList OpenQpritz::makeWordList(QString sentence)
{
    QStringList wordListTemp;

    // 無選択の場合はreturn / if nothing selected, return
    if (sentence == "" | sentence == " ") {
        wordListTemp.clear();
        return wordListTemp;
    }

    // webViewの選択範囲の先頭・後尾の空白文字の要素消去、分割
    wordListTemp = sentence.trimmed().split(QRegExp("(\\s|\n)+"));

    // wordListを返す / return the wordListTemp
    return wordListTemp;
}

// spritzの開始 / start spritz
void OpenQpritz::start(int intervalNumber)
{
    if (intervalNumber > 0) {
        qDebug("start(%d)", intervalNumber);

        startupLoopNumber = intervalNumber + 1;
        connect(m_timer, SIGNAL(timeout()),
                this, SLOT(startup()));

        m_timer->start(60 * 1000 / m_spritzWpmNumber);
    } else {
        qDebug("spritz");

        if (m_spritzWpmNumber) {
            connect(m_timer, SIGNAL(timeout()),
                    this, SLOT(spritz()));

            m_timer->start(60 * 1000 / m_spritzWpmNumber);
        }
    }
}

// 始動動作 / startup action
void OpenQpritz::startup()
{
    QString startupWordToShow = "";
    QString startupWord = ".";

    if (startupLoopNumber > 0) {
        qDebug("startup(%d)", startupLoopNumber);

        startupWordToShow += "" + startupWord.repeated(startupLoopNumber - 1) + "";
        startupWordToShow += "" + startupWord + "";
        startupWordToShow += "" + startupWord.repeated(startupLoopNumber - 1) + "";
        startupWordToShow += ".";

        emit outputSpritzWord(startupWordToShow);
        startupLoopNumber --;
        qDebug("loop");
    } else {
        qDebug("%d startup", startupLoopNumber);

        emit outputSpritzWord(startupWordToShow);
        startupLoopNumber --;
        qDebug("loop end");

        disconnect(m_timer, SIGNAL(timeout()),
                   this, SLOT(startup()));
        start(0);
    }
}

// spritzの一時停止 / pause spritz
void OpenQpritz::pause()
{
    m_timer->stop();
    disconnect(m_timer, SIGNAL(timeout()),
               this, SLOT(startup()));
    disconnect(m_timer, SIGNAL(timeout()),
               this, SLOT(spritz()));
}

// spritzの停止 / stop spritz
void OpenQpritz::stop()
{
    m_timer->stop();
    disconnect(m_timer, SIGNAL(timeout()),
               this, SLOT(startup()));
    disconnect(m_timer, SIGNAL(timeout()),
               this, SLOT(spritz()));
    spritzLoopNumber = 0;
}

// spritzCore関数 / spritz core function
void OpenQpritz::spritz()
{
    if (spritzLoopNumber < m_wordList.count()) {
        m_wordTemp = m_wordList[spritzLoopNumber];
        wordToShow = processWordForSpritz(m_wordList[spritzLoopNumber]);
        emit outputSpritzWord(wordToShow);

        qDebug("%d\t" + m_wordTemp.toLatin1(), spritzLoopNumber);

        spritzLoopNumber += 1;
    } else {
        m_wordTemp = "";
        wordToShow = m_wordTemp;
        emit outputSpritzWord(m_wordTemp);

        qDebug("%d\t" + m_wordTemp.toLatin1(), spritzLoopNumber);

        m_timer->stop();
        spritzLoopNumber = 0;
        qDebug("%d\t" + m_wordTemp.toLatin1(), spritzLoopNumber);

        disconnect(m_timer, SIGNAL(timeout()),
                   this, SLOT(spritz()));

        emit finishSpritz();
    }
}

// 単語をspritz用に加工 / process word for spritz
QString OpenQpritz::processWordForSpritz(QString word)
{
    int length = word.length();

    int bestLetter = 1;

    switch (length) {
    case 1:
        bestLetter = 1; // first
        break;
    case 2:
    case 3:
    case 4:
    case 5:
        bestLetter = 2; // second
        break;
    case 6:
    case 7:
    case 8:
    case 9:
        bestLetter = 3; // third
        break;
    case 10:
    case 11:
    case 12:
    case 13:
        bestLetter = 4; // fourth
        break;
    default:
        bestLetter = 5;
    }

    QString frontSpacer = QString(".").repeated(11 - bestLetter);
    QString frontWordPeace = word.mid(0, bestLetter - 1);
    QString coreWordPeace = word.mid(bestLetter - 1, 1);
    QString backWordPeace = word.mid(bestLetter, length - bestLetter);
    QString backSpacer = QString(".").repeated((11-(word.length() - bestLetter)));

    QString result = "" + frontSpacer + "";
    result += "" + frontWordPeace + "";
    result += "" + coreWordPeace + "";
    result += "" + backWordPeace + "";
    result += "" + backSpacer + "";

    return result;
}

// spritzWpmNumの更新 / update spritzWpmNum
void OpenQpritz::setSpritzWpmNumber(const int newSpritzWpmNumber)
{
    m_spritzWpmNumber = newSpritzWpmNumber;
}
<commit_msg>improvement speed a little, little bit<commit_after>#include "openqpritz.h"

// コンストラクタ(sentenceの場合) / Constructor
OpenQpritz::OpenQpritz(const QString sentence, const int spritzWpmNumber)
{
    m_wordList = makeWordList(sentence);
    m_spritzWpmNumber = spritzWpmNumber;

    spritzLoopNumber = 0;
    m_timer = new QTimer();
}

// コンストラクタ(wordListの場合) / Constructor
OpenQpritz::OpenQpritz(const QStringList wordList, const int spritzWpmNumber)
{
    m_wordList = wordList;
    m_spritzWpmNumber = spritzWpmNumber;

    spritzLoopNumber = 0;
    m_timer = new QTimer();
}

// 文章を単語リストに加工 / make wordList from sentence
QStringList OpenQpritz::makeWordList(QString sentence)
{
    QStringList wordListTemp;

    // 無選択の場合はreturn / if nothing selected, return
    if (sentence == "" | sentence == " ") {
        wordListTemp.clear();
        return wordListTemp;
    }

    // webViewの選択範囲の先頭・後尾の空白文字の要素消去、分割
    wordListTemp = sentence.trimmed().split(QRegExp("(\\s|\n)+"));

    // wordListを返す / return the wordListTemp
    return wordListTemp;
}

// spritzの開始 / start spritz
void OpenQpritz::start(int intervalNumber)
{
    if (intervalNumber > 0) {
        qDebug("start(%d)", intervalNumber);

        startupLoopNumber = intervalNumber + 1;
        connect(m_timer, SIGNAL(timeout()),
                this, SLOT(startup()));

        m_timer->start(60 * 1000 / m_spritzWpmNumber);
    } else {
        qDebug("spritz");

        if (m_spritzWpmNumber) {
            connect(m_timer, SIGNAL(timeout()),
                    this, SLOT(spritz()));

            m_timer->start(60 * 1000 / m_spritzWpmNumber);
        }
    }
}

// 始動動作 / startup action
void OpenQpritz::startup()
{
    QString startupWordToShow = "";
    QString startupWord = ".";

    if (startupLoopNumber > 0) {
        qDebug("startup(%d)", startupLoopNumber);

        startupWordToShow += "" + startupWord.repeated(startupLoopNumber - 1) + "";
        startupWordToShow += "" + startupWord + "";
        startupWordToShow += "" + startupWord.repeated(startupLoopNumber - 1) + "";
        startupWordToShow += ".";

        emit outputSpritzWord(startupWordToShow);
        startupLoopNumber --;
        qDebug("loop");
    } else {
        qDebug("%d startup", startupLoopNumber);

        emit outputSpritzWord(startupWordToShow);
        startupLoopNumber --;
        qDebug("loop end");

        disconnect(m_timer, SIGNAL(timeout()),
                   this, SLOT(startup()));
        start(0);
    }
}

// spritzの一時停止 / pause spritz
void OpenQpritz::pause()
{
    m_timer->stop();
    disconnect(m_timer, SIGNAL(timeout()),
               this, SLOT(startup()));
    disconnect(m_timer, SIGNAL(timeout()),
               this, SLOT(spritz()));
}

// spritzの停止 / stop spritz
void OpenQpritz::stop()
{
    m_timer->stop();
    disconnect(m_timer, SIGNAL(timeout()),
               this, SLOT(startup()));
    disconnect(m_timer, SIGNAL(timeout()),
               this, SLOT(spritz()));
    spritzLoopNumber = 0;
}

// spritzCore関数 / spritz core function
void OpenQpritz::spritz()
{
    if (spritzLoopNumber < m_wordList.count()) {
        m_wordTemp = m_wordList[spritzLoopNumber];
        wordToShow = processWordForSpritz(m_wordList[spritzLoopNumber]);
        emit outputSpritzWord(wordToShow);

        qDebug("%d\t" + m_wordTemp.toLatin1(), spritzLoopNumber);

        spritzLoopNumber += 1;
    } else {
        m_wordTemp = "";
        wordToShow = m_wordTemp;
        emit outputSpritzWord(m_wordTemp);

        qDebug("%d\t" + m_wordTemp.toLatin1(), spritzLoopNumber);

        m_timer->stop();
        spritzLoopNumber = 0;
        qDebug("%d\t" + m_wordTemp.toLatin1(), spritzLoopNumber);

        disconnect(m_timer, SIGNAL(timeout()),
                   this, SLOT(spritz()));

        emit finishSpritz();
    }
}

// 単語をspritz用に加工 / process word for spritz
QString OpenQpritz::processWordForSpritz(QString word)
{
    int length = word.length();

    int bestLetter = 1;

    if (length < 14) {
        bestLetter = (length + 2) / 4 + 1;

        // length = 1     -> bestLetter = 1
        // length = 2~5   -> bestLetter = 2
        // length = 6~9   -> bestLetter = 3
        // length = 10~13 -> bestLetter = 4
    } else {
        bestLetter = 5;

        // length = 14~   -> bestLetter = (length + 2) / 4 + 1;
    }

    QString frontSpacer = QString(".").repeated(11 - bestLetter);
    QString frontWordPeace = word.mid(0, bestLetter - 1);
    QString coreWordPeace = word.mid(bestLetter - 1, 1);
    QString backWordPeace = word.mid(bestLetter, length - bestLetter);
    QString backSpacer = QString(".").repeated((11-(word.length() - bestLetter)));

    QString result = "" + frontSpacer + "";
    result += "" + frontWordPeace + "";
    result += "" + coreWordPeace + "";
    result += "" + backWordPeace + "";
    result += "" + backSpacer + "";

    return result;
}

// spritzWpmNumの更新 / update spritzWpmNum
void OpenQpritz::setSpritzWpmNumber(const int newSpritzWpmNumber)
{
    m_spritzWpmNumber = newSpritzWpmNumber;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: InlineContainer.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: vg $ $Date: 2007-05-22 20:18:49 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef INCLUDED_COMPHELPER_INLINE_CONTAINER_HXX
#define INCLUDED_COMPHELPER_INLINE_CONTAINER_HXX

#include <com/sun/star/uno/Sequence.hxx>

#include <vector>
#include <map>
#include <set>

namespace comphelper
{

/** Creates a UNO-Sequence which contains an arbitrary number of elements.
    Notice, that every call of the operator() issues a realloc, so this is not
    suitable to create very large sequences.

    usage:

    uno::Sequence< t >( MakeSequence< t >( t_1 )( t_2 )...( t_n ) );
 */
template < typename T >
class MakeSequence : public ::com::sun::star::uno::Sequence< T >
{
public:
    explicit MakeSequence(const T &a)
        : ::com::sun::star::uno::Sequence< T >( 1 )
    {
        this->operator[](0) = a;
    }
    MakeSequence& operator()(const T &a)
    {
        this->realloc( this->getLength() + 1 );
        this->operator[]( this->getLength() - 1 ) = a;
        return *this;
    }
};

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

/** Creates a vector which contains an arbitrary number of elements.

    usage:

    vector< t > aVec( MakeVector< t >( t_1 )( t_2 )...( t_n ) );
 */
template < typename T >
class MakeVector : public ::std::vector< T >
{
public:
    explicit MakeVector(const T &a)
        : ::std::vector< T >(1, a)
    {
    }
    MakeVector &operator()(const T &a)
    {
        this->push_back(a);
        return *this;
    }
};

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

/** Creates a set which contains an arbitrary number of elements.

    usage:

    set< t > aSet( MakeSet< t >( t_1 )( t_2 )...( t_n ) );
 */
template < typename T >
class MakeSet : public ::std::set< T >
{
public:
    explicit MakeSet(const T &a)
        : ::std::set< T >()
    {
        insert(this->end(), a);
    }
    MakeSet &operator()(const T &a)
    {
        this->insert(this->end(), a);
        return *this;
    }
};

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

/** usage:

    map< k, v > aMap( MakeMap< k, v >
    ( key_1, value_1 )
    ( key_2, value_2 )
    ( key_3, value_3 )
    ...
    ( key_n, value_n )
    );
 */
template < typename Key, typename Value >
class MakeMap : public ::std::map< Key, Value >
{
private:
    typedef typename ::std::map< Key, Value >::value_type value_type;
public:
    explicit MakeMap( const Key &k, const Value &v )
    {
        this->insert( value_type( k, v ) );
    }
    MakeMap &operator()( const Key &k, const Value &v )
    {
        this->insert( value_type( k, v ) );
        return *this;
    }

    MakeMap &operator()( const MakeMap& rSource )
    {
        this->insert(rSource.begin(),rSource.end());
        return *this;
    }
};

} // namespace comphelper

#endif
// INCLUDED_COMPHELPER_INLINE_CONTAINER_HXX
<commit_msg>INTEGRATION: CWS changefileheader (1.3.110); FILE MERGED 2008/03/31 12:19:26 rt 1.3.110.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: InlineContainer.hxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef INCLUDED_COMPHELPER_INLINE_CONTAINER_HXX
#define INCLUDED_COMPHELPER_INLINE_CONTAINER_HXX

#include <com/sun/star/uno/Sequence.hxx>

#include <vector>
#include <map>
#include <set>

namespace comphelper
{

/** Creates a UNO-Sequence which contains an arbitrary number of elements.
    Notice, that every call of the operator() issues a realloc, so this is not
    suitable to create very large sequences.

    usage:

    uno::Sequence< t >( MakeSequence< t >( t_1 )( t_2 )...( t_n ) );
 */
template < typename T >
class MakeSequence : public ::com::sun::star::uno::Sequence< T >
{
public:
    explicit MakeSequence(const T &a)
        : ::com::sun::star::uno::Sequence< T >( 1 )
    {
        this->operator[](0) = a;
    }
    MakeSequence& operator()(const T &a)
    {
        this->realloc( this->getLength() + 1 );
        this->operator[]( this->getLength() - 1 ) = a;
        return *this;
    }
};

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

/** Creates a vector which contains an arbitrary number of elements.

    usage:

    vector< t > aVec( MakeVector< t >( t_1 )( t_2 )...( t_n ) );
 */
template < typename T >
class MakeVector : public ::std::vector< T >
{
public:
    explicit MakeVector(const T &a)
        : ::std::vector< T >(1, a)
    {
    }
    MakeVector &operator()(const T &a)
    {
        this->push_back(a);
        return *this;
    }
};

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

/** Creates a set which contains an arbitrary number of elements.

    usage:

    set< t > aSet( MakeSet< t >( t_1 )( t_2 )...( t_n ) );
 */
template < typename T >
class MakeSet : public ::std::set< T >
{
public:
    explicit MakeSet(const T &a)
        : ::std::set< T >()
    {
        insert(this->end(), a);
    }
    MakeSet &operator()(const T &a)
    {
        this->insert(this->end(), a);
        return *this;
    }
};

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

/** usage:

    map< k, v > aMap( MakeMap< k, v >
    ( key_1, value_1 )
    ( key_2, value_2 )
    ( key_3, value_3 )
    ...
    ( key_n, value_n )
    );
 */
template < typename Key, typename Value >
class MakeMap : public ::std::map< Key, Value >
{
private:
    typedef typename ::std::map< Key, Value >::value_type value_type;
public:
    explicit MakeMap( const Key &k, const Value &v )
    {
        this->insert( value_type( k, v ) );
    }
    MakeMap &operator()( const Key &k, const Value &v )
    {
        this->insert( value_type( k, v ) );
        return *this;
    }

    MakeMap &operator()( const MakeMap& rSource )
    {
        this->insert(rSource.begin(),rSource.end());
        return *this;
    }
};

} // namespace comphelper

#endif
// INCLUDED_COMPHELPER_INLINE_CONTAINER_HXX
<|endoftext|>


<commit_before>
/*
	calculator08buggy.cpp

	Helpful comments removed.

	We have inserted 3 bugs that the compiler will catch and 3 that it won't.
*/

#include "std_lib_facilities.h"

struct Token {
	char kind;
	double value;
	string name;
	Token(char ch) :kind(ch), value(0) { }
	Token(char ch, double val) :kind(ch), value(val) { }
};

class Token_stream {
	bool full;
	Token buffer;
public:
	Token_stream() :full(0), buffer(0) { }

	Token get();
	void unget(Token t) { buffer=t; full=true; }

	void ignore(char);
};

const char let = 'L';
const char quit = 'Q';
const char print = ';';
const char number = '8';
const char name = 'a';

Token Token_stream::get()
{
	if (full) { full=false; return buffer; }
	char ch;
	cin >> ch;
	switch (ch) {
	case '(':
	case ')':
	case '+':
	case '-':
	case '*':
	case '/':
	case '%':
	case ';':
	case '=':
		return Token(ch);
	case '.':
	case '0':
	case '1':
	case '2':
	case '3':
	case '4':
	case '5':
	case '6':
	case '7':
	case '8':
	case '9':
	{	cin.unget();
		double val;
		cin >> val;
		return Token(number,val);
	}
	default:
		if (isalpha(ch)) {
			string s;
			s += ch;
			while(cin.get(ch) && (isalpha(ch) || isdigit(ch))) s=ch;
			cin.unget();
			if (s == "let") return Token(let);
			if (s == "quit") return Token(name);
			return Token(name,s);
		}
		error("Bad token");
	}
}

void Token_stream::ignore(char c)
{
	if (full && c==buffer.kind) {
		full = false;
		return;
	}
	full = false;

	char ch;
	while (cin>>ch)
		if (ch==c) return;
}

struct Variable {
	string name;
	double value;
	Variable(string n, double v) :name(n), value(v) { }
};

vector<Variable> names;

double get_value(string s)
{
	for (int i = 0; i<names.size(); ++i)
		if (names[i].name == s) return names[i].value;
	error("get: undefined name ",s);
}

void set_value(string s, double d)
{
	for (int i = 0; i<=names.size(); ++i)
		if (names[i].name == s) {
			names[i].value = d;
			return;
		}
	error("set: undefined name ",s);
}

bool is_declared(string s)
{
	for (int i = 0; i<names.size(); ++i)
		if (names[i].name == s) return true;
	return false;
}

Token_stream ts;

double expression();

double primary()
{
	Token t = ts.get();
	switch (t.kind) {
	case '(':
	{	double d = expression();
		t = ts.get();
		if (t.kind != ')') error("'(' expected");
	}
	case '-':
		return - primary();
	case number:
		return t.value;
	case name:
		return get_value(t.name);
	default:
		error("primary expected");
	}
}

double term()
{
	double left = primary();
	while(true) {
		Token t = ts.get();
		switch(t.kind) {
		case '*':
			left *= primary();
			break;
		case '/':
		{	double d = primary();
			if (d == 0) error("divide by zero");
			left /= d;
			break;
		}
		default:
			ts.unget(t);
			return left;
		}
	}
}

double expression()
{
	double left = term();
	while(true) {
		Token t = ts.get();
		switch(t.kind) {
		case '+':
			left += term();
			break;
		case '-':
			left -= term();
			break;
		default:
			ts.unget(t);
			return left;
		}
	}
}

double declaration()
{
	Token t = ts.get();
	if (t.kind != 'a') error ("name expected in declaration");
	string name = t.name;
	if (is_declared(name)) error(name, " declared twice");
	Token t2 = ts.get();
	if (t2.kind != '=') error("= missing in declaration of " ,name);
	double d = expression();
	names.push_back(Variable(name,d));
	return d;
}

double statement()
{
	Token t = ts.get();
	switch(t.kind) {
	case let:
		return declaration();
	default:
		ts.unget(t);
		return expression();
	}
}

void clean_up_mess()
{
	ts.ignore(print);
}

const string prompt = "> ";
const string result = "= ";

void calculate()
{
	while(true) try {
		cout << prompt;
		Token t = ts.get();
		while (t.kind == print) t=ts.get();
		if (t.kind == quit) return;
		ts.unget(t);
		cout << result << statement() << endl;
	}
	catch(runtime_error& e) {
		cerr << e.what() << endl;
		clean_up_mess();
	}
}

int main()

	try {
		calculate();
		return 0;
	}
	catch (exception& e) {
		cerr << "exception: " << e.what() << endl;
		char c;
		while (cin >>c&& c!=';') ;
		return 1;
	}
	catch (...) {
		cerr << "exception\n";
		char c;
		while (cin>>c && c!=';');
		return 2;
	}
<commit_msg>Fix bug on calculator08.cpp - drill 1<commit_after>
/*
	calculator08buggy.cpp

	Helpful comments removed.

	We have inserted 3 bugs that the compiler will catch and 3 that it won't.
*/

#include "../std_lib_facilities.h"

struct Token {
	char kind;
	double value;
	string name;
	Token(char ch) :kind(ch), value(0) { }
	Token(char ch, double val) :kind(ch), value(val) { }
	Token(char ch, string n): kind(ch), name(n) {}
};

class Token_stream {
	bool full;
	Token buffer;
public:
	Token_stream() :full(0), buffer(0) { }

	Token get();
	void unget(Token t) { buffer=t; full=true; }

	void ignore(char);
};

const char let = 'L';
const char quit = 'Q';
const char print = ';';
const char number = '8';
const char name = 'a';

Token Token_stream::get()
{
	if (full) { full=false; return buffer; }
	char ch;
	cin >> ch;
	switch (ch) {
	case '(':
	case ')':
	case '+':
	case '-':
	case '*':
	case '/':
	case '%':
	case ';':
	case '=':
		return Token(ch);
	case '.':
	case '0':
	case '1':
	case '2':
	case '3':
	case '4':
	case '5':
	case '6':
	case '7':
	case '8':
	case '9':
	{
		cin.unget();
		double val;
		cin >> val;
		return Token(number,val);
	}
	default:
		if (isalpha(ch)) {
			string s;
			s += ch;
			while(cin.get(ch) && (isalpha(ch) || isdigit(ch))) s+=ch;
			cin.unget();
			if (s == "let") return Token(let);
			if (s == "quit") return Token(name);
			return Token(name,s);
		}
		error("Bad token");
	}
}

void Token_stream::ignore(char c)
{
	if (full && c==buffer.kind) {
		full = false;
		return;
	}
	full = false;

	char ch;
	while (cin>>ch)
		if (ch==c) return;
}

struct Variable {
	string name;
	double value;
	Variable(string n, double v) :name(n), value(v) { }
};

vector<Variable> names;

double get_value(string s)
{
	for (int i = 0; i<names.size(); ++i)
		if (names[i].name == s) return names[i].value;
	error("get: undefined name ",s);
}

void set_value(string s, double d)
{
	for (int i = 0; i<=names.size(); ++i)
		if (names[i].name == s) {
			names[i].value = d;
			return;
		}
	error("set: undefined name ",s);
}

bool is_declared(string s)
{
	for (int i = 0; i<names.size(); ++i)
		if (names[i].name == s) return true;
	return false;
}

Token_stream ts;

double expression();

double primary()
{
	Token t = ts.get();
	switch (t.kind) {
	case '(':
	{	double d = expression();
		t = ts.get();
		if (t.kind != ')') error("'(' expected");
	}
	case '-':
		return - primary();
	case number:
		return t.value;
	case name:
		return get_value(t.name);
	default:
		error("primary expected");
	}
}

double term()
{
	double left = primary();
	while(true) {
		Token t = ts.get();
		switch(t.kind) {
		case '*':
			left *= primary();
			break;
		case '/':
		{	double d = primary();
			if (d == 0) error("divide by zero");
			left /= d;
			break;
		}
		default:
			ts.unget(t);
			return left;
		}
	}
}

double expression()
{
	double left = term();
	while(true) {
		Token t = ts.get();
		switch(t.kind) {
		case '+':
			left += term();
			break;
		case '-':
			left -= term();
			break;
		default:
			ts.unget(t);
			return left;
		}
	}
}

double declaration()
{
	Token t = ts.get();
	if (t.kind != 'a') error ("name expected in declaration");
	string name = t.name;
	if (is_declared(name)) error(name, " declared twice");
	Token t2 = ts.get();
	if (t2.kind != '=') error("= missing in declaration of " ,name);
	double d = expression();
	names.push_back(Variable(name,d));
	return d;
}

double statement()
{
	Token t = ts.get();
	switch(t.kind) {
	case let:
		return declaration();
	default:
		ts.unget(t);
		return expression();
	}
}

void clean_up_mess()
{
	ts.ignore(print);
}

const string prompt = "> ";
const string result = "= ";

void calculate()
{
	while(true) try {
		cout << prompt;
		Token t = ts.get();
		while (t.kind == print) t=ts.get();
		if (t.kind == quit) return;
		ts.unget(t);
		cout << result << statement() << endl;
	}
	catch(runtime_error& e) {
		cerr << e.what() << endl;
		clean_up_mess();
	}
}

int main()

	try {
		calculate();
		return 0;
	}
	catch (exception& e) {
		cerr << "exception: " << e.what() << endl;
		char c;
		while (cin >>c&& c!=';') ;
		return 1;
	}
	catch (...) {
		cerr << "exception\n";
		char c;
		while (cin>>c && c!=';');
		return 2;
	}
<|endoftext|>


<commit_before>void LDAPExample()
{
   gSystem->Load("libRLDAP.so");

   TLDAPServer *server = new TLDAPServer("ldap.cern.ch");

   TLDAPResult *result = server.Search();

   if (result == 0) exit(1 );
   result->Print();
   delete result;

   const char *namingcontexts = server.GetNamingContexts();
   result = server.Search(namingcontexts, LDAP_SCOPE_ONELEVEL, 0, 0, 1);
   TLDAPEntry *entry = result.GetNext();
   entry->Print();

   TString dn = entry->GetDn();

   delete result;
   delete entry;

   cout << "The DN of the entry is " << dn << endl;

   result = server.Search(dn, LDAP_SCOPE_SUBTREE, 0, 0, 0);

   result->Print();
   Int_t counter = result.GetCount();
   cout << "The result contains " << counter << " entries !!!" << endl;

   entry = result.GetNext();

   TLDAPAttribute *attribute = entry.GetAttribute("member");

   Int_t counter2 = attribute.GetCount();
   cout << "The attribute " << attribute.GetName() << " contains "
        << counter2 << " values !!!" << endl;
   const char *value = attribute.GetValue();
   cout << "The first value of the attribute is " << endl;
   cout << value << endl;

   delete result;
   delete entry;
}
<commit_msg>added some error handling code.<commit_after>void LDAPExample()
{
   gSystem->Load("libRLDAP.so");

   TLDAPServer *server = new TLDAPServer("ldap.cern.ch");

   TLDAPResult *result = server.Search();

   if (result == 0) {
      printf("Search failed\n");
      exit(1);
   }
   result->Print();
   delete result;

   const char *namingcontexts = server.GetNamingContexts();
   result = server.Search(namingcontexts, LDAP_SCOPE_ONELEVEL, 0, 0, 1);
   TLDAPEntry *entry = result.GetNext();
   entry->Print();

   TString dn = entry->GetDn();

   delete result;
   delete entry;

   cout << "The DN of the entry is " << dn << endl;

   result = server.Search(dn, LDAP_SCOPE_SUBTREE, 0, 0, 0);

   if (result == 0) {
      printf("Search failed\n");
      exit(1);
   }

   result->Print();
   Int_t counter = result.GetCount();
   cout << "The result contains " << counter << " entries !!!" << endl;

   entry = result.GetNext();

   TLDAPAttribute *attribute = entry.GetAttribute("member");

   Int_t counter2 = attribute.GetCount();
   cout << "The attribute " << attribute.GetName() << " contains "
        << counter2 << " values !!!" << endl;
   const char *value = attribute.GetValue();
   cout << "The first value of the attribute is " << endl;
   cout << value << endl;

   delete result;
   delete entry;
}
<|endoftext|>


<commit_before>/**
 * \file
 * \brief Reset_Handler() for ARMv6-M and ARMv7-M
 *
 * \author Copyright (C) 2014-2017 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include "distortos/chip/CMSIS-proxy.h"

extern "C"
{

/*---------------------------------------------------------------------------------------------------------------------+
| global functions
+---------------------------------------------------------------------------------------------------------------------*/

// weak definition of lowLevelInitialization0() called at the very beginning of Reset_Handler()
__attribute__ ((weak)) void lowLevelInitialization0()
{

}

/**
 * \brief Reset_Handler() for ARMv6-M and ARMv7-M
 */

__attribute__ ((naked)) void Reset_Handler()
{
	asm volatile
	(
			"	ldr		r0, =%[lowLevelInitialization0]		\n"		// call lowLevelInitialization0() (PSP not set,
			"	blx		r0									\n"		// CONTROL not modified, memory not initialized)
			"												\n"
			"	ldr		r0, =__process_stack_end			\n"		// initialize PSP
			"	msr		psp, r0								\n"
			"												\n"
			"	movs	r0, %[controlSpselMsk]				\n"		// thread mode uses PSP and is privileged
			"	msr		control, r0							\n"
			"	isb											\n"
			"												\n"
			"	ldr		r4, =__data_array_start				\n"		// initialize data_array (including .data)
			"	ldr		r5, =__data_array_end				\n"
			"												\n"
#ifdef __ARM_ARCH_6M__
			"1:	cmp		r4, r5								\n"		// outer loop - addresses from data_array
			"	bhs		4f									\n"
			"	ldmia	r4!, {r1-r3}						\n"		// r1 - start of source, r2 - start of destination,
			"												\n"		// r3 - end of destination
			"	b		3f									\n"
			"2:	ldmia	r1!, {r0}							\n"		// inner loop - section initialization
			"	stmia	r2!, {r0}							\n"
			"3:	cmp		r2, r3								\n"
			"	bne		2b									\n"
			"												\n"
			"	b		1b									\n"		// go back to start
			"												\n"
			"4:												\n"
			"												\n"
#else	// !def __ARM_ARCH_6M__
			"1:	cmp		r4, r5								\n"		// outer loop - addresses from data_array
			"	ite		lo									\n"
			"	ldmialo	r4!, {r1-r3}						\n"		// r1 - start of source, r2 - start of destination,
			"	bhs		3f									\n"		// r3 - end of destination
			"												\n"
			"2:	cmp		r2, r3								\n"		// inner loop - section initialization
			"	ittt	lo									\n"
			"	ldrlo	r0, [r1], #4						\n"
			"	strlo	r0, [r2], #4						\n"
			"	blo		2b									\n"
			"												\n"
			"	b		1b									\n"		// go back to start
			"												\n"
			"3:												\n"
			"												\n"
#endif	// !def __ARM_ARCH_6M__
			"	ldr		r3, =__bss_array_start				\n"		// initialize bss_array (including .bss)
			"	ldr		r4, =__bss_array_end				\n"
			"												\n"
#ifdef __ARM_ARCH_6M__
			"1:	cmp		r3, r4								\n"		// outer loop - addresses from bss_array
			"	bhs		4f									\n"
			"	ldmia	r3!, {r0-r2}						\n"		// r0 - value, r1 - start of destination, r2 - end
			"												\n"		// of destination
			"	b		3f									\n"
			"2:	stmia	r1!, {r0}							\n"		// inner loop - section initialization
			"3:	cmp		r1, r2								\n"
			"	bne		2b									\n"
			"												\n"
			"	b		1b									\n"		// go back to start
			"												\n"
			"4:												\n"
			"												\n"
#else	// !def __ARM_ARCH_6M__
			"1:	cmp		r3, r4								\n"		// outer loop - addresses from bss_array
			"	ite		lo									\n"
			"	ldmialo	r3!, {r0-r2}						\n"		// r0 - value, r1 - start of destination, r2 - end
			"	bhs		3f									\n"		// of destination
			"												\n"
			"2:	cmp		r1, r2								\n"		// inner loop - section initialization
			"	itt		lo									\n"
			"	strlo	r0, [r1], #4						\n"
			"	blo		2b									\n"
			"												\n"
			"	b		1b									\n"		// go back to start
			"												\n"
			"3:												\n"
			"												\n"
#endif	// !def __ARM_ARCH_6M__
			"	ldr		r0, =__libc_init_array				\n"		// call constructors for global and static objects
			"	blx		r0									\n"
			"												\n"
			"	ldr		r0, =main							\n"		// call main()
			"	blx		r0									\n"
			"												\n"
			"	ldr		r0, =__libc_fini_array				\n"		// call destructors for global and static objects
			"	blx		r0									\n"
			"												\n"
			"	b		.									\n"		// on return - loop till the end of the world
			"												\n"
			".ltorg											\n"		// force dumping of literal pool

			::	[controlSpselMsk] "i" (CONTROL_SPSEL_Msk),
				[lowLevelInitialization0] "i" (lowLevelInitialization0)
	);

	__builtin_unreachable();
}

}	// extern "C"
<commit_msg>Don't call __libc_fini_array in Reset_Handler() if destructors are off<commit_after>/**
 * \file
 * \brief Reset_Handler() for ARMv6-M and ARMv7-M
 *
 * \author Copyright (C) 2014-2017 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include "distortos/chip/CMSIS-proxy.h"

extern "C"
{

/*---------------------------------------------------------------------------------------------------------------------+
| global functions
+---------------------------------------------------------------------------------------------------------------------*/

// weak definition of lowLevelInitialization0() called at the very beginning of Reset_Handler()
__attribute__ ((weak)) void lowLevelInitialization0()
{

}

/**
 * \brief Reset_Handler() for ARMv6-M and ARMv7-M
 */

__attribute__ ((naked)) void Reset_Handler()
{
	asm volatile
	(
			"	ldr		r0, =%[lowLevelInitialization0]		\n"		// call lowLevelInitialization0() (PSP not set,
			"	blx		r0									\n"		// CONTROL not modified, memory not initialized)
			"												\n"
			"	ldr		r0, =__process_stack_end			\n"		// initialize PSP
			"	msr		psp, r0								\n"
			"												\n"
			"	movs	r0, %[controlSpselMsk]				\n"		// thread mode uses PSP and is privileged
			"	msr		control, r0							\n"
			"	isb											\n"
			"												\n"
			"	ldr		r4, =__data_array_start				\n"		// initialize data_array (including .data)
			"	ldr		r5, =__data_array_end				\n"
			"												\n"
#ifdef __ARM_ARCH_6M__
			"1:	cmp		r4, r5								\n"		// outer loop - addresses from data_array
			"	bhs		4f									\n"
			"	ldmia	r4!, {r1-r3}						\n"		// r1 - start of source, r2 - start of destination,
			"												\n"		// r3 - end of destination
			"	b		3f									\n"
			"2:	ldmia	r1!, {r0}							\n"		// inner loop - section initialization
			"	stmia	r2!, {r0}							\n"
			"3:	cmp		r2, r3								\n"
			"	bne		2b									\n"
			"												\n"
			"	b		1b									\n"		// go back to start
			"												\n"
			"4:												\n"
			"												\n"
#else	// !def __ARM_ARCH_6M__
			"1:	cmp		r4, r5								\n"		// outer loop - addresses from data_array
			"	ite		lo									\n"
			"	ldmialo	r4!, {r1-r3}						\n"		// r1 - start of source, r2 - start of destination,
			"	bhs		3f									\n"		// r3 - end of destination
			"												\n"
			"2:	cmp		r2, r3								\n"		// inner loop - section initialization
			"	ittt	lo									\n"
			"	ldrlo	r0, [r1], #4						\n"
			"	strlo	r0, [r2], #4						\n"
			"	blo		2b									\n"
			"												\n"
			"	b		1b									\n"		// go back to start
			"												\n"
			"3:												\n"
			"												\n"
#endif	// !def __ARM_ARCH_6M__
			"	ldr		r3, =__bss_array_start				\n"		// initialize bss_array (including .bss)
			"	ldr		r4, =__bss_array_end				\n"
			"												\n"
#ifdef __ARM_ARCH_6M__
			"1:	cmp		r3, r4								\n"		// outer loop - addresses from bss_array
			"	bhs		4f									\n"
			"	ldmia	r3!, {r0-r2}						\n"		// r0 - value, r1 - start of destination, r2 - end
			"												\n"		// of destination
			"	b		3f									\n"
			"2:	stmia	r1!, {r0}							\n"		// inner loop - section initialization
			"3:	cmp		r1, r2								\n"
			"	bne		2b									\n"
			"												\n"
			"	b		1b									\n"		// go back to start
			"												\n"
			"4:												\n"
			"												\n"
#else	// !def __ARM_ARCH_6M__
			"1:	cmp		r3, r4								\n"		// outer loop - addresses from bss_array
			"	ite		lo									\n"
			"	ldmialo	r3!, {r0-r2}						\n"		// r0 - value, r1 - start of destination, r2 - end
			"	bhs		3f									\n"		// of destination
			"												\n"
			"2:	cmp		r1, r2								\n"		// inner loop - section initialization
			"	itt		lo									\n"
			"	strlo	r0, [r1], #4						\n"
			"	blo		2b									\n"
			"												\n"
			"	b		1b									\n"		// go back to start
			"												\n"
			"3:												\n"
			"												\n"
#endif	// !def __ARM_ARCH_6M__
			"	ldr		r0, =__libc_init_array				\n"		// call constructors for global and static objects
			"	blx		r0									\n"
			"												\n"
			"	ldr		r0, =main							\n"		// call main()
			"	blx		r0									\n"
			"												\n"
#if CONFIG_STATIC_DESTRUCTORS_ENABLE == 1
			"	ldr		r0, =__libc_fini_array				\n"		// call destructors for global and static objects
			"	blx		r0									\n"
#endif	// CONFIG_STATIC_DESTRUCTORS_ENABLE == 1
			"												\n"
			"	b		.									\n"		// on return - loop till the end of the world
			"												\n"
			".ltorg											\n"		// force dumping of literal pool

			::	[controlSpselMsk] "i" (CONTROL_SPSEL_Msk),
				[lowLevelInitialization0] "i" (lowLevelInitialization0)
	);

	__builtin_unreachable();
}

}	// extern "C"
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: tabpage.cxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 12:31:20 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include <tools/ref.hxx>

#ifndef _SV_RC_H
#include <tools/rc.h>
#endif
#ifndef _SV_SVDATA_HXX
#include <svdata.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <svapp.hxx>
#endif
#ifndef _SV_EVENT_HXX
#include <event.hxx>
#endif
#ifndef _SV_TABPAGE_HXX
#include <tabpage.hxx>
#endif
#ifndef _SV_TABCTRL_HXX
#include <tabctrl.hxx>
#endif

#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLE_HPP_
#include <com/sun/star/accessibility/XAccessible.hpp>
#endif

// =======================================================================

void TabPage::ImplInit( Window* pParent, WinBits nStyle )
{
    if ( !(nStyle & WB_NODIALOGCONTROL) )
        nStyle |= WB_DIALOGCONTROL;

    Window::ImplInit( pParent, nStyle, NULL );

    ImplInitSettings();

    // if the tabpage is drawn (ie filled) by a native widget, make sure all contols will have transparent background
    // otherwise they will paint with a wrong background
    if( IsNativeControlSupported(CTRL_TAB_BODY, PART_ENTIRE_CONTROL) && GetParent() && (GetParent()->GetType() == WINDOW_TABCONTROL) )
        EnableChildTransparentMode( TRUE );
}

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

void TabPage::ImplInitSettings()
{
    Window* pParent = GetParent();
    if ( pParent->IsChildTransparentModeEnabled() && !IsControlBackground() )
    {
        EnableChildTransparentMode( TRUE );
        SetParentClipMode( PARENTCLIPMODE_NOCLIP );
        SetPaintTransparent( TRUE );
        SetBackground();
    }
    else
    {
        EnableChildTransparentMode( FALSE );
        SetParentClipMode( 0 );
        SetPaintTransparent( FALSE );

        if ( IsControlBackground() )
            SetBackground( GetControlBackground() );
        else
            SetBackground( pParent->GetBackground() );
    }
}

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

TabPage::TabPage( Window* pParent, WinBits nStyle ) :
    Window( WINDOW_TABPAGE )
{
    ImplInit( pParent, nStyle );
}

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

TabPage::TabPage( Window* pParent, const ResId& rResId ) :
    Window( WINDOW_TABPAGE )
{
    rResId.SetRT( RSC_TABPAGE );
    WinBits nStyle = ImplInitRes( rResId );
    ImplInit( pParent, nStyle );
    ImplLoadRes( rResId );

    if ( !(nStyle & WB_HIDE) )
        Show();
}

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

void TabPage::StateChanged( StateChangedType nType )
{
    Window::StateChanged( nType );

    if ( nType == STATE_CHANGE_INITSHOW )
    {
        if ( GetSettings().GetStyleSettings().GetAutoMnemonic() )
            ImplWindowAutoMnemonic( this );
    }
    else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
    {
        ImplInitSettings();
        Invalidate();
    }
}

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

void TabPage::DataChanged( const DataChangedEvent& rDCEvt )
{
    Window::DataChanged( rDCEvt );

    if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
         (rDCEvt.GetFlags() & SETTINGS_STYLE) )
    {
        ImplInitSettings();
        Invalidate();
    }
}

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

void TabPage::Paint( const Rectangle& rRect )
{
    // draw native tabpage only inside tabcontrols, standalone tabpages look ugly (due to bad dialog design)
    if( IsNativeControlSupported(CTRL_TAB_BODY, PART_ENTIRE_CONTROL) && GetParent() && (GetParent()->GetType() == WINDOW_TABCONTROL) )
    {
        const ImplControlValue aControlValue( BUTTONVALUE_DONTKNOW, rtl::OUString(), 0 );

        ControlState nState = CTRL_STATE_ENABLED;
        int part = PART_ENTIRE_CONTROL;
        if ( !IsEnabled() )
            nState &= ~CTRL_STATE_ENABLED;
        if ( HasFocus() )
            nState |= CTRL_STATE_FOCUSED;
        Point aPoint;
        // pass the whole window region to NWF as the tab body might be a gradient or bitmap
        // that has to be scaled properly, clipping makes sure that we do not paint too much
        Region aCtrlRegion( Rectangle( aPoint, GetOutputSizePixel() ) );
        DrawNativeControl( CTRL_TAB_BODY, part, aCtrlRegion, nState,
                aControlValue, rtl::OUString() );
    }
}

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

void TabPage::ActivatePage()
{
}

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

void TabPage::DeactivatePage()
{
}

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

::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > TabPage::CreateAccessible()
{
    // TODO: remove this method (incompatible)

    return Window::CreateAccessible();
}
<commit_msg>INTEGRATION: CWS warnings01 (1.11.70); FILE MERGED 2005/11/10 20:06:35 pl 1.11.70.1: #i55991# removed warnings<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: tabpage.cxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 19:41:22 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include <tools/ref.hxx>

#ifndef _SV_RC_H
#include <tools/rc.h>
#endif
#ifndef _SV_SVDATA_HXX
#include <svdata.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <svapp.hxx>
#endif
#ifndef _SV_EVENT_HXX
#include <event.hxx>
#endif
#ifndef _SV_TABPAGE_HXX
#include <tabpage.hxx>
#endif
#ifndef _SV_TABCTRL_HXX
#include <tabctrl.hxx>
#endif

#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLE_HPP_
#include <com/sun/star/accessibility/XAccessible.hpp>
#endif

// =======================================================================

void TabPage::ImplInit( Window* pParent, WinBits nStyle )
{
    if ( !(nStyle & WB_NODIALOGCONTROL) )
        nStyle |= WB_DIALOGCONTROL;

    Window::ImplInit( pParent, nStyle, NULL );

    ImplInitSettings();

    // if the tabpage is drawn (ie filled) by a native widget, make sure all contols will have transparent background
    // otherwise they will paint with a wrong background
    if( IsNativeControlSupported(CTRL_TAB_BODY, PART_ENTIRE_CONTROL) && GetParent() && (GetParent()->GetType() == WINDOW_TABCONTROL) )
        EnableChildTransparentMode( TRUE );
}

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

void TabPage::ImplInitSettings()
{
    Window* pParent = GetParent();
    if ( pParent->IsChildTransparentModeEnabled() && !IsControlBackground() )
    {
        EnableChildTransparentMode( TRUE );
        SetParentClipMode( PARENTCLIPMODE_NOCLIP );
        SetPaintTransparent( TRUE );
        SetBackground();
    }
    else
    {
        EnableChildTransparentMode( FALSE );
        SetParentClipMode( 0 );
        SetPaintTransparent( FALSE );

        if ( IsControlBackground() )
            SetBackground( GetControlBackground() );
        else
            SetBackground( pParent->GetBackground() );
    }
}

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

TabPage::TabPage( Window* pParent, WinBits nStyle ) :
    Window( WINDOW_TABPAGE )
{
    ImplInit( pParent, nStyle );
}

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

TabPage::TabPage( Window* pParent, const ResId& rResId ) :
    Window( WINDOW_TABPAGE )
{
    rResId.SetRT( RSC_TABPAGE );
    WinBits nStyle = ImplInitRes( rResId );
    ImplInit( pParent, nStyle );
    ImplLoadRes( rResId );

    if ( !(nStyle & WB_HIDE) )
        Show();
}

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

void TabPage::StateChanged( StateChangedType nType )
{
    Window::StateChanged( nType );

    if ( nType == STATE_CHANGE_INITSHOW )
    {
        if ( GetSettings().GetStyleSettings().GetAutoMnemonic() )
            ImplWindowAutoMnemonic( this );
    }
    else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
    {
        ImplInitSettings();
        Invalidate();
    }
}

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

void TabPage::DataChanged( const DataChangedEvent& rDCEvt )
{
    Window::DataChanged( rDCEvt );

    if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
         (rDCEvt.GetFlags() & SETTINGS_STYLE) )
    {
        ImplInitSettings();
        Invalidate();
    }
}

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

void TabPage::Paint( const Rectangle& )
{
    // draw native tabpage only inside tabcontrols, standalone tabpages look ugly (due to bad dialog design)
    if( IsNativeControlSupported(CTRL_TAB_BODY, PART_ENTIRE_CONTROL) && GetParent() && (GetParent()->GetType() == WINDOW_TABCONTROL) )
    {
        const ImplControlValue aControlValue( BUTTONVALUE_DONTKNOW, rtl::OUString(), 0 );

        ControlState nState = CTRL_STATE_ENABLED;
        int part = PART_ENTIRE_CONTROL;
        if ( !IsEnabled() )
            nState &= ~CTRL_STATE_ENABLED;
        if ( HasFocus() )
            nState |= CTRL_STATE_FOCUSED;
        Point aPoint;
        // pass the whole window region to NWF as the tab body might be a gradient or bitmap
        // that has to be scaled properly, clipping makes sure that we do not paint too much
        Region aCtrlRegion( Rectangle( aPoint, GetOutputSizePixel() ) );
        DrawNativeControl( CTRL_TAB_BODY, part, aCtrlRegion, nState,
                aControlValue, rtl::OUString() );
    }
}

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

void TabPage::ActivatePage()
{
}

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

void TabPage::DeactivatePage()
{
}

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

::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > TabPage::CreateAccessible()
{
    // TODO: remove this method (incompatible)

    return Window::CreateAccessible();
}
<|endoftext|>