<commit_before>// Best-first Utility-Guided Search Yes! From:
// "Best-first Utility-Guided Search," Wheeler Ruml and Minh B. Do,
// Proceedings of the Twentieth International Joint Conference on
// Artificial Intelligence (IJCAI-07), 2007

#include "../search/search.hpp"
#include "../structs/binheap.hpp"
#include "../utils/pool.hpp"

template <class D> struct Bugsy : public SearchAlgorithm<D> {
	typedef typename D::State State;
	typedef typename D::PackedState PackedState;
	typedef typename D::Cost Cost;
	typedef typename D::Oper Oper;

	struct Node : SearchNode<D> {
		typename D::Cost f, h, d;
		double u, t;

		static bool pred(Node *a, Node *b) {
			if (a->u != b->u)
				return a->u > b->u;
			if (a->t != b->t)
				return a->t < b->t;
			if (a->f != b->f)
				return a->f < b->f;
			return a->g > b->g;
		}
	};

	Bugsy(int argc, const char *argv[]) :
			SearchAlgorithm<D>(argc, argv),
			timeper(0.0), nresort(0), pertick(20), nexp(0), state(WaitTick),
			closed(30000001) {
		wf = wt = -1;
		for (int i = 0; i < argc; i++) {
			if (i < argc - 1 && strcmp(argv[i], "-wf") == 0)
				wf = strtod(argv[++i], NULL);
			else if (i < argc - 1 && strcmp(argv[i], "-wt") == 0)
				wt = strtod(argv[++i], NULL);
		}

		if (wf < 0)
			fatal("Must specify non-negative f-weight using -wf");
		if (wt < 0)
			fatal("Must specify non-negative t-weight using -wt");

		nodes = new Pool<Node>();
	}

	~Bugsy(void) {
		delete nodes;
	}

	enum { WaitTick, ExpandSome, WaitExpand };

	void search(D &d, typename D::State &s0) {
		this->start();
		closed.init(d);
		Node *n0 = init(d, s0);
		closed.add(n0);
		open.push(n0);

		lasttick = walltime();
		while (!open.empty() && !SearchAlgorithm<D>::limit()) {
			updatetime();

			Node* n = *open.pop();
			State buf, &state = d.unpack(buf, n->packed);
			if (d.isgoal(state)) {
				SearchAlgorithm<D>::res.goal(d, n);
				break;
			}
			expand(d, n, state);
		}

		this->finish();
	}

	virtual void reset(void) {
		SearchAlgorithm<D>::reset();
		open.clear();
		closed.clear();
		delete nodes;
		timeper = 0.0;
		state = WaitTick;
		pertick = 20;
		nexp = 0;
		nresort = 0;
		nodes = new Pool<Node>();
	}

	virtual void output(FILE *out) {
		SearchAlgorithm<D>::output(out);
		closed.prstats(stdout, "closed ");
		dfpair(stdout, "open list type", "%s", "binary heap");
		dfpair(stdout, "node size", "%u", sizeof(Node));
		dfpair(stdout, "wt", "%g", wt);
		dfpair(stdout, "wf", "%g", wf);
		dfpair(stdout, "final time per expand", "%g", timeper);
		dfpair(stdout, "number of resorts", "%lu", nresort);
	}

private:

	void expand(D &d, Node *n, State &state) {
		SearchAlgorithm<D>::res.expd++;

		typename D::Operators ops(d, state);
		for (unsigned int i = 0; i < ops.size(); i++) {
			if (ops[i] == n->pop)
				continue;
			SearchAlgorithm<D>::res.gend++;
			considerkid(d, n, state, ops[i]);
		}
	}

	void considerkid(D &d, Node *parent, State &state, Oper op) {
		Node *kid = nodes->construct();
		typename D::Edge e(d, state, op);
		kid->g = parent->g + e.cost;
		d.pack(kid->packed, e.state);

		unsigned long hash = d.hash(kid->packed);
		Node *dup = static_cast<Node*>(closed.find(kid->packed, hash));
		if (dup) {
			this->res.dups++;
			if (kid->g >= dup->g) {
				nodes->destruct(kid);
				return;
			}
			this->res.reopnd++;
			dup->f = dup->f - dup->g + kid->g;
			dup->update(kid->g, parent, op, e.revop);
			computeutil(dup);
			open.pushupdate(dup, dup->ind);
			nodes->destruct(kid);
		} else {
			kid->d = d.d(e.state);
			kid->h = d.h(e.state);
			kid->f = kid->g + kid->h;
			kid->update(kid->g, parent, op, e.revop);
			computeutil(kid);
			closed.add(kid, hash);
			open.push(kid);
		}
	}

	Node *init(D &d, State &s0) {
		Node *n0 = nodes->construct();
		d.pack(n0->packed, s0);
		n0->g = Cost(0);
		n0->h = n0->f = d.h(s0);
		n0->d = d.d(s0);
		computeutil(n0);
		n0->op = n0->pop = D::Nop;
		n0->parent = NULL;
		return n0;
	}

	void computeutil(Node *n) {
		n->t = timeper * n->d;
		n->u = -(wf * n->f + wt * n->t);
	}

	void updatetime(void) {
		double now;
		nexp++;

		switch (state) {
		case WaitTick:
			now = walltime();
			if (now <= lasttick)
				break;
			starttime = now;
			state = ExpandSome;
			break;

		case ExpandSome:
			if (nexp < pertick)
				break;
			lasttick = walltime();
			state = WaitExpand;
			break;

		case WaitExpand:
			now = walltime();
			if (now <= lasttick)
				break;
			updateopen();
			timeper = (now - starttime) / nexp;
			// 1.8 * nexp from Wheeler's bugsy_old.ml
			pertick = nexp * 9 / 5;
			nexp = 0;
			starttime = now;
			state = ExpandSome;
			break;

		default:
			fatal("Unknown update time state: %d\n", state);
		}
	}

	void updateopen(void) {
		nresort++;
		for (int i = 0; i < open.size(); i++)
			computeutil(open.at(i));
		open.reinit();
	}

	double wf, wt;

	// for nodes-per-second estimation
	double timeper;
	unsigned long nresort, pertick, nexp;
	double starttime, lasttick;
	int state;

	BinHeap<Node, Node*> open;
 	ClosedList<SearchNode<D>, SearchNode<D>, D> closed;
	Pool<Node> *nodes;
};
<commit_msg>bugsy: heuristic and distance corrections. This is nearly the same as the BUGSY implementation that Wheeler used in the original BUGSY paper.  The only difference is that this implementation does not take into account the nearest goal, only the cheapest.<commit_after>// Best-first Utility-Guided Search Yes! From:
// "Best-first Utility-Guided Search," Wheeler Ruml and Minh B. Do,
// Proceedings of the Twentieth International Joint Conference on
// Artificial Intelligence (IJCAI-07), 2007

#include "../search/search.hpp"
#include "../structs/binheap.hpp"
#include "../utils/pool.hpp"

template <class D> struct Bugsy : public SearchAlgorithm<D> {
	typedef typename D::State State;
	typedef typename D::PackedState PackedState;
	typedef typename D::Cost Cost;
	typedef typename D::Oper Oper;

	struct Node : SearchNode<D> {
		typename D::Cost f, h, d;
		double u, t;

		static bool pred(Node *a, Node *b) {
			if (a->u != b->u)
				return a->u > b->u;
			if (a->t != b->t)
				return a->t < b->t;
			if (a->f != b->f)
				return a->f < b->f;
			return a->g > b->g;
		}
	};

	Bugsy(int argc, const char *argv[]) :
			SearchAlgorithm<D>(argc, argv),
			navg(0), herror(0), derror(0),
			timeper(0.0), nresort(0), batchsize(20), nexp(0), state(WaitTick),
			closed(30000001) {
		wf = wt = -1;
		for (int i = 0; i < argc; i++) {
			if (i < argc - 1 && strcmp(argv[i], "-wf") == 0)
				wf = strtod(argv[++i], NULL);
			else if (i < argc - 1 && strcmp(argv[i], "-wt") == 0)
				wt = strtod(argv[++i], NULL);
		}

		if (wf < 0)
			fatal("Must specify non-negative f-weight using -wf");
		if (wt < 0)
			fatal("Must specify non-negative t-weight using -wt");

		nodes = new Pool<Node>();
	}

	~Bugsy(void) {
		delete nodes;
	}

	enum { WaitTick, ExpandSome, WaitExpand };

	void search(D &d, typename D::State &s0) {
		this->start();
		closed.init(d);
		Node *n0 = init(d, s0);
		closed.add(n0);
		open.push(n0);

		lasttick = walltime();
		while (!open.empty() && !SearchAlgorithm<D>::limit()) {
			updatetime();

			Node* n = *open.pop();
			State buf, &state = d.unpack(buf, n->packed);
			if (d.isgoal(state)) {
				SearchAlgorithm<D>::res.goal(d, n);
				break;
			}
			expand(d, n, state);
		}

		this->finish();
	}

	virtual void reset(void) {
		SearchAlgorithm<D>::reset();
		open.clear();
		closed.clear();
		delete nodes;
		timeper = 0.0;
		state = WaitTick;
		batchsize = 20;
		nexp = 0;
		nresort = 0;
		nodes = new Pool<Node>();
	}

	virtual void output(FILE *out) {
		SearchAlgorithm<D>::output(out);
		closed.prstats(stdout, "closed ");
		dfpair(stdout, "open list type", "%s", "binary heap");
		dfpair(stdout, "node size", "%u", sizeof(Node));
		dfpair(stdout, "cost weight", "%g", wf);
		dfpair(stdout, "time weight", "%g", wt);
		dfpair(stdout, "final time per expand", "%g", timeper);
		dfpair(stdout, "number of resorts", "%lu", nresort);
		dfpair(stdout, "mean single-step h error", "%g", herror);
		dfpair(stdout, "mean single-step d error", "%g", derror);
	}

private:

	// Kidinfo holds information about a node used for
	// correcting the heuristic estimates.
	struct Kidinfo {
		Kidinfo(void) : f(-1), h(-1), d(-1) { }

		Kidinfo(Cost g, Cost _h, Cost _d) : f(g + _h), h(_h), d(_d) { }

		Cost f, h, d;
	};

	// expand expands the node, adding its children to the
	// open and closed lists as appropriate.
	void expand(D &d, Node *n, State &state) {
		this->res.expd++;
		Kidinfo bestinfo;

		typename D::Operators ops(d, state);
		for (unsigned int i = 0; i < ops.size(); i++) {
			if (ops[i] == n->pop)
				continue;

			this->res.gend++;
			Kidinfo kinfo = considerkid(d, n, state, ops[i]);
			if (bestinfo.f < Cost(0) || kinfo.f < bestinfo.f)
				bestinfo = kinfo;
		}

		if (bestinfo.f < Cost(0))
			return;

		navg++;
		double herr = bestinfo.f - n->f;
		herror = herror + (herr - herror)/navg;
		double derr = bestinfo.d + 1 - n->d;
		derror = derror + (derr - derror)/navg;
	}

	// considers adding the child generated via the given
	// operator to the open and closed lists.  The return is
	// the info struct for the generated child.
	Kidinfo considerkid(D &d, Node *parent, State &state, Oper op) {
		Node *kid = nodes->construct();
		typename D::Edge e(d, state, op);
		kid->g = parent->g + e.cost;
		d.pack(kid->packed, e.state);

		unsigned long hash = d.hash(kid->packed);
		Node *dup = static_cast<Node*>(closed.find(kid->packed, hash));
		if (dup) {
			this->res.dups++;
			if (kid->g < dup->g) {
				this->res.reopnd++;
				dup->f = dup->f - dup->g + kid->g;
				dup->update(kid->g, parent, op, e.revop);
				computeutil(dup);
				open.pushupdate(dup, dup->ind);
			}
			Kidinfo kinfo(kid->g, dup->h, dup->d);
			nodes->destruct(kid);
			return kinfo;
		}

		kid->d = d.d(e.state);
		kid->h = d.h(e.state);
		kid->f = kid->g + kid->h;
		kid->update(kid->g, parent, op, e.revop);
		computeutil(kid);
		closed.add(kid, hash);
		open.push(kid);
		return Kidinfo(kid->g, kid->h, kid->d);
	}

	Node *init(D &d, State &s0) {
		Node *n0 = nodes->construct();
		d.pack(n0->packed, s0);
		n0->g = Cost(0);
		n0->h = n0->f = d.h(s0);
		n0->d = d.d(s0);
		computeutil(n0);
		n0->op = n0->pop = D::Nop;
		n0->parent = NULL;
		return n0;
	}

	// compututil computes the utility value of the given node
	// using corrected estimates of d and h.
	void computeutil(Node *n) {
		double dhat = n->d / (1 - derror);
		double hhat = n->h + dhat * herror;
		double fhat = hhat + n->g;
		n->t = timeper * dhat;
		n->u = -(wf * fhat + wt * n->t);
	}

	// updatetime runs a simple state machine (from Wheeler's BUGSY
	// implementation) that estimates the node expansion rate.
	void updatetime(void) {
		double now;

		switch (state) {
		case WaitTick:	// wait until the clock ticks
			now = walltime();
			if (now <= lasttick)
				break;
			starttime = now;
			state = ExpandSome;
			break;

		case ExpandSome:	// expand a batch of nodes
			nexp++;
			if (nexp < batchsize)
				break;
			lasttick = walltime();
			state = WaitExpand;
			break;

		case WaitExpand:	// estimate the exps for the next tick and reset
			nexp++;
			now = walltime();
			if (now <= lasttick)	// clock hasn't ticked yet
				break;
			updateopen();
			timeper = (now - starttime) / nexp;
			// Re-check the time after 1.8*nexp expansions.
			// 1.8 is from Wheeler's bugsy_old.ml code.  This
			// should be geometrically increasing in nexp to
			// ensure that we only sort the open list a logarithmic
			// number of times.
			batchsize = nexp * 9 / 5;
			nexp = 0;
			starttime = now;
			state = ExpandSome;
			break;

		default:
			fatal("Unknown update time state: %d\n", state);
		}
	}

	void updateopen(void) {
		nresort++;
		for (int i = 0; i < open.size(); i++)
			computeutil(open.at(i));
		open.reinit();
	}

	double wf, wt;

	// heuristic correction
	unsigned long navg;
	double herror, derror;

	// for nodes-per-second estimation
	double timeper;
	unsigned long nresort, batchsize, nexp;
	double starttime, lasttick;
	int state;

	BinHeap<Node, Node*> open;
 	ClosedList<SearchNode<D>, SearchNode<D>, D> closed;
	Pool<Node> *nodes;
};
<|endoftext|>


<commit_before>#include "mpclient.h"

using namespace mpc_rfid;

MPClient::MPClient(const std::string &host, uint16_t port)
{
	mpd_host = host;
	mpd_port = port;

	my_mpd_conn = NULL;
	mpd_info = new mpd_info_s;
	mpd_info_song = new mpd_info_song_s;
}

MPClient::~MPClient()
{
	if (my_mpd_conn) mpd_connection_free(my_mpd_conn);
	delete mpd_info_song;
	delete mpd_info;
}

int MPClient::connect()
{
	my_mpd_conn = mpd_connection_new(mpd_host.empty() ? 0 : mpd_host.c_str(), mpd_port, 30000);
	if (mpd_connection_get_error(my_mpd_conn) != MPD_ERROR_SUCCESS) {
		return 1;
	}
	return 0;
}

int MPClient::disconnect()
{
	if (my_mpd_conn) {
	       mpd_connection_free(my_mpd_conn);
	       return 0;
	}
	return 1;
}

void MPClient::update_status()
{
	mpd_info_song->title.clear();

	mpd_command_list_begin(my_mpd_conn, true);
	mpd_send_status(my_mpd_conn);
	mpd_send_current_song(my_mpd_conn);
	mpd_command_list_end(my_mpd_conn);
	my_mpd_status = mpd_recv_status(my_mpd_conn);
	if (my_mpd_status != 0) { // success
		mpd_info->volume = mpd_status_get_volume(my_mpd_status);
		mpd_info->state = mpd_status_get_state(my_mpd_status);
		if (mpd_info->state == MPD_STATE_PLAY || mpd_info->state == MPD_STATE_PAUSE) {
			mpd_info->elapsed_time = mpd_status_get_elapsed_time(my_mpd_status);
			mpd_info_song->kbit_rate = mpd_status_get_kbit_rate(my_mpd_status);
		}
		mpd_audio_format = mpd_status_get_audio_format(my_mpd_status);
		if (mpd_audio_format != NULL) {
			mpd_info_song->sample_rate = mpd_audio_format->sample_rate;
			mpd_info_song->channels = mpd_audio_format->channels;
			mpd_info_song->bits = mpd_audio_format->bits;
		}

		mpd_status_free(my_mpd_status);

		if (mpd_connection_get_error(my_mpd_conn) == MPD_ERROR_SUCCESS) {
			mpd_response_next(my_mpd_conn);
			my_mpd_song = mpd_recv_song(my_mpd_conn);
			if (my_mpd_song != NULL) {
				mpd_info_song->title = get_song_tag_or_empty(MPD_TAG_TITLE);
				mpd_info_song->album = get_song_tag_or_empty(MPD_TAG_ALBUM);
				mpd_info_song->artist = get_song_tag_or_empty(MPD_TAG_ARTIST);
			}
		} else {
			// error
		}
	} else {
		// error
	}
	mpd_response_finish(my_mpd_conn);
}

bool MPClient::add_and_play(const std::string &playfile)
{
	bool status;
	uint8_t tries = 3;

	while (tries > 0) {
		status = do_add_and_play(playfile);
		if (status) break;
		disconnect();
		connect();
		tries -= 1;
	}

	return status;
}

bool MPClient::do_add_and_play(const std::string &playfile)
{
	bool status;
	while (1) {
		status = mpd_run_clear(my_mpd_conn);
		if (mpd_connection_get_error(my_mpd_conn) != MPD_ERROR_SUCCESS) {
			printf("error: %s\n", mpd_connection_get_error_message(my_mpd_conn));
			break;
		}
		status = mpd_run_add(my_mpd_conn, playfile.c_str());
		if (mpd_connection_get_error(my_mpd_conn) != MPD_ERROR_SUCCESS) {
			printf("error: %s\n", mpd_connection_get_error_message(my_mpd_conn));
			break;
		}
		status = mpd_run_play(my_mpd_conn);
		if (mpd_connection_get_error(my_mpd_conn) != MPD_ERROR_SUCCESS) {
			printf("error: %s\n", mpd_connection_get_error_message(my_mpd_conn));
			break;
		}
		break;
	}

	return status;
}

void MPClient::print_status()const
{
	printf("mpc: volume: %i\n", get_info_volume());
	printf("mpc: state: ");
	switch (get_info_state()) {
		case MPD_STATE_STOP:
			printf("stop\n");
			break;
		case MPD_STATE_PLAY:
			printf("play\n");
			break;
		case MPD_STATE_PAUSE:
			printf("pause\n");
			break;
	}
	printf("mpc: time: %i\n", get_info_elapsed_time());
	printf("mpc: audio: %iHz/%ibit", get_info_sample_rate(), get_info_bits());
	switch(get_info_channels()) {
		case 0:
		case 1: // mono
			printf("\n");
			break;
		case 2: // stereo
			printf("/st\n");
			break;
		default: // multi-channel
			printf("/mc\n");
			break;
	}
	printf("mpc: title: %s\n", get_info_title().c_str());
	printf("mpc: album: %s\n", get_info_album().c_str());
}

std::string MPClient::get_song_tag_or_empty(mpd_tag_type tag_type)const
{
	const char *tag_value = mpd_song_get_tag(my_mpd_song, tag_type, 0);
	std::string tag_value_str = tag_value == NULL ? "" : std::string(tag_value);
	return tag_value_str;
}

int MPClient::get_info_volume()const
{
	return mpd_info->volume;
}

uint8_t MPClient::get_info_state()const
{
	return mpd_info->state;
}

uint16_t MPClient::get_info_elapsed_time()const
{
	return mpd_info->elapsed_time;
}

uint8_t MPClient::get_info_kbit_rate()const
{
	return mpd_info_song->kbit_rate;
}

uint32_t MPClient::get_info_sample_rate()const
{
	return mpd_info_song->sample_rate;
}

uint8_t MPClient::get_info_channels()const
{
	return mpd_info_song->channels;
}

uint8_t MPClient::get_info_bits()const
{
	return mpd_info_song->bits;
}

std::string MPClient::get_info_title()const
{
	return mpd_info_song->title;
}

std::string MPClient::get_info_album()const
{
	return mpd_info_song->album;
}

std::string MPClient::get_info_artist()const
{
	return mpd_info_song->artist;
}

<commit_msg>Code review: minor changes to mpclient<commit_after>#include "mpclient.h"

using namespace mpc_rfid;

MPClient::MPClient(const std::string &host, uint16_t port)
{
	mpd_host = host;
	mpd_port = port;

	my_mpd_conn = NULL;
	mpd_info = new mpd_info_s;
	mpd_info_song = new mpd_info_song_s;
}

MPClient::~MPClient()
{
	if (my_mpd_conn) mpd_connection_free(my_mpd_conn);
	delete mpd_info_song;
	delete mpd_info;
}

int MPClient::connect()
{
	my_mpd_conn = mpd_connection_new(mpd_host.empty() ? 0 : mpd_host.c_str(), mpd_port, 30000);
	if (mpd_connection_get_error(my_mpd_conn) != MPD_ERROR_SUCCESS) {
		return 1;
	}
	return 0;
}

int MPClient::disconnect()
{
	if (my_mpd_conn) {
	       mpd_connection_free(my_mpd_conn);
	       return 0;
	}
	return 1;
}

void MPClient::update_status()
{
	mpd_info_song->title.clear();

	mpd_command_list_begin(my_mpd_conn, true);
	mpd_send_status(my_mpd_conn);
	mpd_send_current_song(my_mpd_conn);
	mpd_command_list_end(my_mpd_conn);
	my_mpd_status = mpd_recv_status(my_mpd_conn);
	if (my_mpd_status != 0) { // success
		mpd_info->volume = mpd_status_get_volume(my_mpd_status);
		mpd_info->state = mpd_status_get_state(my_mpd_status);
		if (mpd_info->state == MPD_STATE_PLAY || mpd_info->state == MPD_STATE_PAUSE) {
			mpd_info->elapsed_time = mpd_status_get_elapsed_time(my_mpd_status);
			mpd_info_song->kbit_rate = mpd_status_get_kbit_rate(my_mpd_status);
		}
		mpd_audio_format = mpd_status_get_audio_format(my_mpd_status);
		if (mpd_audio_format != NULL) {
			mpd_info_song->sample_rate = mpd_audio_format->sample_rate;
			mpd_info_song->channels = mpd_audio_format->channels;
			mpd_info_song->bits = mpd_audio_format->bits;
		}

		mpd_status_free(my_mpd_status);

		if (mpd_connection_get_error(my_mpd_conn) == MPD_ERROR_SUCCESS) {
			mpd_response_next(my_mpd_conn);
			my_mpd_song = mpd_recv_song(my_mpd_conn);
			if (my_mpd_song != NULL) {
				mpd_info_song->title = get_song_tag_or_empty(MPD_TAG_TITLE);
				mpd_info_song->album = get_song_tag_or_empty(MPD_TAG_ALBUM);
				mpd_info_song->artist = get_song_tag_or_empty(MPD_TAG_ARTIST);
			}
		} else {
			// error
		}
	} else {
		// error
	}
	mpd_response_finish(my_mpd_conn);
}

bool MPClient::add_and_play(const std::string &playfile)
{
	bool status;
	uint8_t tries = 3;

	while (tries > 0) {
		status = do_add_and_play(playfile);
		if (status) break;
		disconnect();
		connect();
		tries -= 1;
	}

	return status;
}

bool MPClient::do_add_and_play(const std::string &playfile)
{
	bool status = mpd_run_clear(my_mpd_conn);
	if (mpd_connection_get_error(my_mpd_conn) != MPD_ERROR_SUCCESS) {
		printf("error: %s\n", mpd_connection_get_error_message(my_mpd_conn));
		return status;
	}
	status = mpd_run_add(my_mpd_conn, playfile.c_str());
	if (mpd_connection_get_error(my_mpd_conn) != MPD_ERROR_SUCCESS) {
		printf("error: %s\n", mpd_connection_get_error_message(my_mpd_conn));
		return status;
	}
	status = mpd_run_play(my_mpd_conn);
	if (mpd_connection_get_error(my_mpd_conn) != MPD_ERROR_SUCCESS) {
		printf("error: %s\n", mpd_connection_get_error_message(my_mpd_conn));
		return status;
	}

	return status;
}

void MPClient::print_status()const
{
	printf("mpc: volume: %i\n", get_info_volume());
	printf("mpc: state: ");
	switch (get_info_state()) {
		case MPD_STATE_STOP:
			printf("stop\n");
			break;
		case MPD_STATE_PLAY:
			printf("play\n");
			break;
		case MPD_STATE_PAUSE:
			printf("pause\n");
			break;
	}
	printf("mpc: time: %i\n", get_info_elapsed_time());
	printf("mpc: audio: %iHz/%ibit", get_info_sample_rate(), get_info_bits());
	switch(get_info_channels()) {
		case 0:
		case 1: // mono
			printf("\n");
			break;
		case 2: // stereo
			printf("/st\n");
			break;
		default: // multi-channel
			printf("/mc\n");
			break;
	}
	printf("mpc: title: %s\n", get_info_title().c_str());
	printf("mpc: album: %s\n", get_info_album().c_str());
}

std::string MPClient::get_song_tag_or_empty(mpd_tag_type tag_type)const
{
	const char *tag_value = mpd_song_get_tag(my_mpd_song, tag_type, 0);
	std::string tag_value_str = tag_value == NULL ? "" : std::string(tag_value);
	return tag_value_str;
}

int MPClient::get_info_volume()const
{
	return mpd_info->volume;
}

uint8_t MPClient::get_info_state()const
{
	return mpd_info->state;
}

uint16_t MPClient::get_info_elapsed_time()const
{
	return mpd_info->elapsed_time;
}

uint8_t MPClient::get_info_kbit_rate()const
{
	return mpd_info_song->kbit_rate;
}

uint32_t MPClient::get_info_sample_rate()const
{
	return mpd_info_song->sample_rate;
}

uint8_t MPClient::get_info_channels()const
{
	return mpd_info_song->channels;
}

uint8_t MPClient::get_info_bits()const
{
	return mpd_info_song->bits;
}

std::string MPClient::get_info_title()const
{
	return mpd_info_song->title;
}

std::string MPClient::get_info_album()const
{
	return mpd_info_song->album;
}

std::string MPClient::get_info_artist()const
{
	return mpd_info_song->artist;
}

<|endoftext|>


<commit_before>/*************************************************************************************
 *  Copyright (C) 2012 by Alejandro Fiestas Olivares <afiestas@kde.org>              *
 *                                                                                *
 *  This program is free software; you can redistribute it and/or                    *
 *  modify it under the terms of the GNU General Public License                      *
 *  as published by the Free Software Foundation; either version 2                   *
 *  of the License, or (at your option) any later version.                           *
 *                                                                                *
 *  This program is distributed in the hope that it will be useful,                  *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of                   *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                    *
 *  GNU General Public License for more details.                                     *
 *                                                                                *
 *  You should have received a copy of the GNU General Public License                *
 *  along with this program; if not, write to the Free Software                      *
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA   *
 *************************************************************************************/

#include "daemon.h"
#include "serializer.h"
#include "generator.h"

#include <kdemacros.h>
#include <KPluginFactory>

#include <kscreen/config.h>
#include <kscreen/configmonitor.h>

K_PLUGIN_FACTORY(KScreenDaemonFactory, registerPlugin<KScreenDaemon>();)
K_EXPORT_PLUGIN(KScreenDaemonFactory("kscreen", "kscreen"))

KScreenDaemon::KScreenDaemon(QObject* parent, const QList< QVariant >& ) : KDEDModule(parent)
{
    connect(Generator::self(), SIGNAL(ready()), SLOT(init()));
}

KScreenDaemon::~KScreenDaemon()
{
    Generator::destroy();
}

void KScreenDaemon::init()
{
    applyConfig();
    monitorForChanges();
}

void KScreenDaemon::applyConfig()
{
    KScreen::Config* config = 0;
    if (Serializer::configExists()) {
        config = Serializer::config(Serializer::currentId());
    } else {
        config = Generator::self()->idealConfig();
    }

    KScreen::Config::setConfig(config);
}

void KScreenDaemon::monitorForChanges()
{
    KScreen::Config* config = KScreen::Config::current();
    KScreen::ConfigMonitor::instance()->addConfig(config);

    KScreen::OutputList outputs = config->outputs();
    Q_FOREACH(KScreen::Output* output, outputs) {
        connect(output, SIGNAL(isConnectedChanged()), SLOT(applyConfig()));
    }
}<commit_msg>Set the backend using setenv<commit_after>/*************************************************************************************
 *  Copyright (C) 2012 by Alejandro Fiestas Olivares <afiestas@kde.org>              *
 *                                                                                *
 *  This program is free software; you can redistribute it and/or                    *
 *  modify it under the terms of the GNU General Public License                      *
 *  as published by the Free Software Foundation; either version 2                   *
 *  of the License, or (at your option) any later version.                           *
 *                                                                                *
 *  This program is distributed in the hope that it will be useful,                  *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of                   *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                    *
 *  GNU General Public License for more details.                                     *
 *                                                                                *
 *  You should have received a copy of the GNU General Public License                *
 *  along with this program; if not, write to the Free Software                      *
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA   *
 *************************************************************************************/

#include "daemon.h"
#include "serializer.h"
#include "generator.h"

#include <kdemacros.h>
#include <KPluginFactory>

#include <kscreen/config.h>
#include <kscreen/configmonitor.h>

K_PLUGIN_FACTORY(KScreenDaemonFactory, registerPlugin<KScreenDaemon>();)
K_EXPORT_PLUGIN(KScreenDaemonFactory("kscreen", "kscreen"))

KScreenDaemon::KScreenDaemon(QObject* parent, const QList< QVariant >& ) : KDEDModule(parent)
{
    setenv("KSCREEN_BACKEND", "XRandR", 1);
    connect(Generator::self(), SIGNAL(ready()), SLOT(init()));
}

KScreenDaemon::~KScreenDaemon()
{
    Generator::destroy();
}

void KScreenDaemon::init()
{
    applyConfig();
    monitorForChanges();
}

void KScreenDaemon::applyConfig()
{
    KScreen::Config* config = 0;
    if (Serializer::configExists()) {
        config = Serializer::config(Serializer::currentId());
    } else {
        config = Generator::self()->idealConfig();
    }

    KScreen::Config::setConfig(config);
}

void KScreenDaemon::monitorForChanges()
{
    KScreen::Config* config = KScreen::Config::current();
    KScreen::ConfigMonitor::instance()->addConfig(config);

    KScreen::OutputList outputs = config->outputs();
    Q_FOREACH(KScreen::Output* output, outputs) {
        connect(output, SIGNAL(isConnectedChanged()), SLOT(applyConfig()));
    }
}<|endoftext|>


<commit_before>/******************************************************************************\
* File:          shell.cpp
* Purpose:       Implementation of class exSTCShell
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id$
*
* Copyright (c) 1998-2009 Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <wx/tokenzr.h>
#include <wx/extension/shell.h>
#include <wx/extension/extension.h>

#if wxUSE_GUI

using namespace std;

/// \todo WX_DELETE is not coming in as an event?
BEGIN_EVENT_TABLE(exSTCShell, exSTC)
//  EVT_CHAR(exSTCShell::OnChar)
  EVT_KEY_DOWN(exSTCShell::OnKey)
  EVT_MENU(wxID_PASTE, exSTCShell::OnCommand)
END_EVENT_TABLE()

exSTCShell::exSTCShell(
  wxWindow* parent,
  const wxString& prompt,
  const wxString& command_end,
  bool echo,
  int commands_save_in_config,
  long menu_flags)
  : exSTC(parent, menu_flags)
  , m_Command(wxEmptyString)
  , m_CommandEnd((command_end == wxEmptyString ? GetEOL(): command_end))
  , m_CommandStartPosition(0)
  , m_Echo(echo)
  // take a char that is not likely to appear inside commands
  , m_CommandsInConfigDelimiter(wxChar(0x03))
  , m_CommandsSaveInConfig(commands_save_in_config)
  , m_Prompt(prompt)
{
  // Override defaults from config.
  SetEdgeMode(wxSTC_EDGE_NONE);
  ResetMargins(false); // do not reset divider margin

  // Start with a prompt.
  Prompt();

  if (m_CommandsSaveInConfig == -1)
  {
    // Fill the list with an empty command.
    KeepCommand();
  }
  else
  {
    // Get all previous commands.
    wxStringTokenizer tkz(exApp::GetConfig("Shell"),
      m_CommandsInConfigDelimiter);

    while (tkz.HasMoreTokens())
    {
      const wxString val = tkz.GetNextToken();
      m_Commands.push_front(val);
    }

    // Take care that m_CommandsIterator is valid.
    if (!m_Commands.empty())
    {
      m_CommandsIterator = m_Commands.end();
    }
    else
    {
      KeepCommand();
    }
  }
}

exSTCShell::~exSTCShell()
{
  if (m_CommandsSaveInConfig > 0)
  {
    wxString values;
    int items = 0;

    for (
      list < wxString >::reverse_iterator it = m_Commands.rbegin();
      it != m_Commands.rend() && items < m_CommandsSaveInConfig;
      it++)
    {
      values += *it + m_CommandsInConfigDelimiter;
      items++;
    }

    exApp::SetConfig("Shell", values);
  }
}

bool exSTCShell::GetHistory(const wxString& short_command)
{
  const int no_asked_for = atoi(short_command.c_str());

  if (no_asked_for > 0)
  {
    int no = 1;

    for (
      list < wxString >::iterator it = m_Commands.begin();
      it != m_Commands.end();
      it++)
    {
      if (no == no_asked_for)
      {
        m_Command = *it;
        return true;
      }

      no++;
    }
  }
  else
  {
    wxString short_command_check;

    if (m_CommandEnd == GetEOL())
    {
      short_command_check = short_command;
    }
    else
    {
      short_command_check =
        short_command.substr(
          0,
          short_command.length() - m_CommandEnd.length());
    }

    for (
      list < wxString >::reverse_iterator it = m_Commands.rbegin();
      it != m_Commands.rend();
      it++)
    {
      const wxString command = *it;

      if (command.StartsWith(short_command_check))
      {
        m_Command = command;
        return true;
      }
    }
  }

  return false;
}

void exSTCShell::KeepCommand()
{
  m_Commands.remove(m_Command);
  m_Commands.push_back(m_Command);

  if (m_Commands.size() == 1)
  {
    m_CommandsIterator = m_Commands.end();
  }
}

void exSTCShell::OnChar(wxKeyEvent& event)
{
  const int key = event.GetKeyCode();
  wxLogMessage("key: %d pos: %d csp: %d", key, GetCurrentPos(), m_CommandStartPosition);
  event.Skip();
}

void exSTCShell::OnCommand(wxCommandEvent& command)
{
  switch (command.GetId())
  {
    case wxID_PASTE:
      // Take care that we cannot paste somewhere inside.
      if (GetCurrentPos() < m_CommandStartPosition)
      {
        DocumentEnd();
      }

      Paste();
      break;

    default: command.Skip();
      break;
  }
}

void exSTCShell::OnKey(wxKeyEvent& event)
{
  const int key = event.GetKeyCode();

  // Enter key pressed, we might have entered a command.
  if (key == WXK_RETURN)
  {
    // First get the command.
    SetTargetStart(GetTextLength());
    SetTargetEnd(0);
    SetSearchFlags(wxSTC_FIND_REGEXP);

    if (SearchInTarget("^" + m_Prompt + ".*") != -1)
    {
      m_Command = GetText().substr(
        GetTargetStart() + m_Prompt.length(),
        GetTextLength() - 1);
      m_Command.Trim();
    }

    if (m_Command.empty())
    {
      Prompt();
    }
    else if (
      m_CommandEnd == GetEOL() ||
      m_Command.EndsWith(m_CommandEnd))
    {
      // We have a command.
      EmptyUndoBuffer();

      // History command.
      if (m_Command == wxString("history") +
         (m_CommandEnd == GetEOL() ? wxString(wxEmptyString): m_CommandEnd))
      {
        KeepCommand();
        ShowHistory();
        Prompt();
      }
      // !.. command, get it from history.
      else if (m_Command.StartsWith("!"))
      {
        if (GetHistory(m_Command.substr(1)))
        {
          AppendText(m_Command);
          KeepCommand();
          wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, ID_SHELL_COMMAND);
          event.SetString(m_Command);
          wxPostEvent(GetParent(), event);
        }
        else
        {
          Prompt(_("event not found"));
        }
      }
      // Other command, send to parent.
      else
      {
        KeepCommand();
        wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, ID_SHELL_COMMAND);
        event.SetString(m_Command);
        wxPostEvent(GetParent(), event);
      }

      m_Command.clear();
    }
    else
    {
      if (m_Echo) event.Skip();
    }

    if (m_Commands.size() > 1)
    {
      m_CommandsIterator = m_Commands.end();
    }
  }
  // Up or down key pressed, and at the end of document.
  else if ((key == WXK_UP || key == WXK_DOWN) &&
            GetCurrentPos() == GetTextLength())
  {
    // There is always an empty command in the list.
    if (m_Commands.size() > 1)
    {
      ShowCommand(key);
    }
  }
  // Home key pressed.
  else if (key == WXK_HOME)
  {
    Home();

    const wxString line = GetLine(GetCurrentLine());

    if (line.StartsWith(m_Prompt))
    {
      GotoPos(GetCurrentPos() + m_Prompt.length());
    }
  }
  // Ctrl-Q pressed, used to stop processing.
  else if (event.GetModifiers() == wxMOD_CONTROL && key == 'Q')
  {
    wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, ID_SHELL_COMMAND_STOP);
    wxPostEvent(GetParent(), event);
  }
  // Ctrl-V pressed, used for pasting as well.
  else if (event.GetModifiers() == wxMOD_CONTROL && key == 'V')
  {
    if (GetCurrentPos() < m_CommandStartPosition) DocumentEnd();
    if (m_Echo) event.Skip();
  }
  // Backspace or delete key pressed.
  else if (key == WXK_BACK || key == WXK_DELETE)
  {
    if (GetCurrentPos() <= m_CommandStartPosition)
    {
      // Ignore, so do nothing.
    }
    else
    {
      // Allow.
      if (m_Echo) event.Skip();
    }
  }
  // The rest.
  else
  {
    // If we enter regular text and not already building a command, first goto end.
    if (event.GetModifiers() == wxMOD_NONE &&
        key < WXK_START &&
        GetCurrentPos() < m_CommandStartPosition)
    {
      DocumentEnd();
    }

    if (m_Commands.size() > 1)
    {
      m_CommandsIterator = m_Commands.end();
    }

    if (m_Echo) event.Skip();
  }
}

void exSTCShell::Prompt(const wxString& text, bool add_eol)
{
  if (!text.empty())
  {
    AppendText(text);
  }

  if (GetTextLength() > 0 && add_eol)
  {
    AppendText(GetEOL());
  }

  AppendText(m_Prompt);

  DocumentEnd();

  m_CommandStartPosition = GetCurrentPos();

  EmptyUndoBuffer();
}

void exSTCShell::ShowCommand(int key)
{
  SetTargetStart(GetTextLength());
  SetTargetEnd(0);
  SetSearchFlags(wxSTC_FIND_REGEXP);

  if (SearchInTarget("^" + m_Prompt + ".*") != -1)
  {
    SetTargetEnd(GetTextLength());

    if (key == WXK_UP)
    {
      if (m_CommandsIterator != m_Commands.begin())
      {
        m_CommandsIterator--;
      }
    }
    else
    {
      if (m_CommandsIterator != m_Commands.end())
      {
        m_CommandsIterator++;
      }
    }

    if (m_CommandsIterator != m_Commands.end())
    {
      ReplaceTarget(m_Prompt + *m_CommandsIterator);
    }
    else
    {
      ReplaceTarget(m_Prompt);
    }

    DocumentEnd();
  }
}

void exSTCShell::ShowHistory()
{
  int command_no = 1;

  for (
    list < wxString >::iterator it = m_Commands.begin();
    it != m_Commands.end();
    it++)
  {
    AppendText(
      wxString::Format("\n%d %s",
        command_no++,
        wxString(*it).c_str()));
  }
}

#endif // wxUSE_GUI
<commit_msg>exSTCShell now depends only on app<commit_after>/******************************************************************************\
* File:          shell.cpp
* Purpose:       Implementation of class exSTCShell
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id$
*
* Copyright (c) 1998-2009 Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <wx/tokenzr.h>
#include <wx/extension/shell.h>
#include <wx/extension/app.h>

#if wxUSE_GUI

using namespace std;

/// \todo WX_DELETE is not coming in as an event?
BEGIN_EVENT_TABLE(exSTCShell, exSTC)
//  EVT_CHAR(exSTCShell::OnChar)
  EVT_KEY_DOWN(exSTCShell::OnKey)
  EVT_MENU(wxID_PASTE, exSTCShell::OnCommand)
END_EVENT_TABLE()

exSTCShell::exSTCShell(
  wxWindow* parent,
  const wxString& prompt,
  const wxString& command_end,
  bool echo,
  int commands_save_in_config,
  long menu_flags)
  : exSTC(parent, menu_flags)
  , m_Command(wxEmptyString)
  , m_CommandEnd((command_end == wxEmptyString ? GetEOL(): command_end))
  , m_CommandStartPosition(0)
  , m_Echo(echo)
  // take a char that is not likely to appear inside commands
  , m_CommandsInConfigDelimiter(wxChar(0x03))
  , m_CommandsSaveInConfig(commands_save_in_config)
  , m_Prompt(prompt)
{
  // Override defaults from config.
  SetEdgeMode(wxSTC_EDGE_NONE);
  ResetMargins(false); // do not reset divider margin

  // Start with a prompt.
  Prompt();

  if (m_CommandsSaveInConfig == -1)
  {
    // Fill the list with an empty command.
    KeepCommand();
  }
  else
  {
    // Get all previous commands.
    wxStringTokenizer tkz(exApp::GetConfig("Shell"),
      m_CommandsInConfigDelimiter);

    while (tkz.HasMoreTokens())
    {
      const wxString val = tkz.GetNextToken();
      m_Commands.push_front(val);
    }

    // Take care that m_CommandsIterator is valid.
    if (!m_Commands.empty())
    {
      m_CommandsIterator = m_Commands.end();
    }
    else
    {
      KeepCommand();
    }
  }
}

exSTCShell::~exSTCShell()
{
  if (m_CommandsSaveInConfig > 0)
  {
    wxString values;
    int items = 0;

    for (
      list < wxString >::reverse_iterator it = m_Commands.rbegin();
      it != m_Commands.rend() && items < m_CommandsSaveInConfig;
      it++)
    {
      values += *it + m_CommandsInConfigDelimiter;
      items++;
    }

    exApp::SetConfig("Shell", values);
  }
}

bool exSTCShell::GetHistory(const wxString& short_command)
{
  const int no_asked_for = atoi(short_command.c_str());

  if (no_asked_for > 0)
  {
    int no = 1;

    for (
      list < wxString >::iterator it = m_Commands.begin();
      it != m_Commands.end();
      it++)
    {
      if (no == no_asked_for)
      {
        m_Command = *it;
        return true;
      }

      no++;
    }
  }
  else
  {
    wxString short_command_check;

    if (m_CommandEnd == GetEOL())
    {
      short_command_check = short_command;
    }
    else
    {
      short_command_check =
        short_command.substr(
          0,
          short_command.length() - m_CommandEnd.length());
    }

    for (
      list < wxString >::reverse_iterator it = m_Commands.rbegin();
      it != m_Commands.rend();
      it++)
    {
      const wxString command = *it;

      if (command.StartsWith(short_command_check))
      {
        m_Command = command;
        return true;
      }
    }
  }

  return false;
}

void exSTCShell::KeepCommand()
{
  m_Commands.remove(m_Command);
  m_Commands.push_back(m_Command);

  if (m_Commands.size() == 1)
  {
    m_CommandsIterator = m_Commands.end();
  }
}

void exSTCShell::OnChar(wxKeyEvent& event)
{
  const int key = event.GetKeyCode();
  wxLogMessage("key: %d pos: %d csp: %d", key, GetCurrentPos(), m_CommandStartPosition);
  event.Skip();
}

void exSTCShell::OnCommand(wxCommandEvent& command)
{
  switch (command.GetId())
  {
    case wxID_PASTE:
      // Take care that we cannot paste somewhere inside.
      if (GetCurrentPos() < m_CommandStartPosition)
      {
        DocumentEnd();
      }

      Paste();
      break;

    default: command.Skip();
      break;
  }
}

void exSTCShell::OnKey(wxKeyEvent& event)
{
  const int key = event.GetKeyCode();

  // Enter key pressed, we might have entered a command.
  if (key == WXK_RETURN)
  {
    // First get the command.
    SetTargetStart(GetTextLength());
    SetTargetEnd(0);
    SetSearchFlags(wxSTC_FIND_REGEXP);

    if (SearchInTarget("^" + m_Prompt + ".*") != -1)
    {
      m_Command = GetText().substr(
        GetTargetStart() + m_Prompt.length(),
        GetTextLength() - 1);
      m_Command.Trim();
    }

    if (m_Command.empty())
    {
      Prompt();
    }
    else if (
      m_CommandEnd == GetEOL() ||
      m_Command.EndsWith(m_CommandEnd))
    {
      // We have a command.
      EmptyUndoBuffer();

      // History command.
      if (m_Command == wxString("history") +
         (m_CommandEnd == GetEOL() ? wxString(wxEmptyString): m_CommandEnd))
      {
        KeepCommand();
        ShowHistory();
        Prompt();
      }
      // !.. command, get it from history.
      else if (m_Command.StartsWith("!"))
      {
        if (GetHistory(m_Command.substr(1)))
        {
          AppendText(m_Command);
          KeepCommand();
          wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, ID_SHELL_COMMAND);
          event.SetString(m_Command);
          wxPostEvent(GetParent(), event);
        }
        else
        {
          Prompt(_("event not found"));
        }
      }
      // Other command, send to parent.
      else
      {
        KeepCommand();
        wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, ID_SHELL_COMMAND);
        event.SetString(m_Command);
        wxPostEvent(GetParent(), event);
      }

      m_Command.clear();
    }
    else
    {
      if (m_Echo) event.Skip();
    }

    if (m_Commands.size() > 1)
    {
      m_CommandsIterator = m_Commands.end();
    }
  }
  // Up or down key pressed, and at the end of document.
  else if ((key == WXK_UP || key == WXK_DOWN) &&
            GetCurrentPos() == GetTextLength())
  {
    // There is always an empty command in the list.
    if (m_Commands.size() > 1)
    {
      ShowCommand(key);
    }
  }
  // Home key pressed.
  else if (key == WXK_HOME)
  {
    Home();

    const wxString line = GetLine(GetCurrentLine());

    if (line.StartsWith(m_Prompt))
    {
      GotoPos(GetCurrentPos() + m_Prompt.length());
    }
  }
  // Ctrl-Q pressed, used to stop processing.
  else if (event.GetModifiers() == wxMOD_CONTROL && key == 'Q')
  {
    wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, ID_SHELL_COMMAND_STOP);
    wxPostEvent(GetParent(), event);
  }
  // Ctrl-V pressed, used for pasting as well.
  else if (event.GetModifiers() == wxMOD_CONTROL && key == 'V')
  {
    if (GetCurrentPos() < m_CommandStartPosition) DocumentEnd();
    if (m_Echo) event.Skip();
  }
  // Backspace or delete key pressed.
  else if (key == WXK_BACK || key == WXK_DELETE)
  {
    if (GetCurrentPos() <= m_CommandStartPosition)
    {
      // Ignore, so do nothing.
    }
    else
    {
      // Allow.
      if (m_Echo) event.Skip();
    }
  }
  // The rest.
  else
  {
    // If we enter regular text and not already building a command, first goto end.
    if (event.GetModifiers() == wxMOD_NONE &&
        key < WXK_START &&
        GetCurrentPos() < m_CommandStartPosition)
    {
      DocumentEnd();
    }

    if (m_Commands.size() > 1)
    {
      m_CommandsIterator = m_Commands.end();
    }

    if (m_Echo) event.Skip();
  }
}

void exSTCShell::Prompt(const wxString& text, bool add_eol)
{
  if (!text.empty())
  {
    AppendText(text);
  }

  if (GetTextLength() > 0 && add_eol)
  {
    AppendText(GetEOL());
  }

  AppendText(m_Prompt);

  DocumentEnd();

  m_CommandStartPosition = GetCurrentPos();

  EmptyUndoBuffer();
}

void exSTCShell::ShowCommand(int key)
{
  SetTargetStart(GetTextLength());
  SetTargetEnd(0);
  SetSearchFlags(wxSTC_FIND_REGEXP);

  if (SearchInTarget("^" + m_Prompt + ".*") != -1)
  {
    SetTargetEnd(GetTextLength());

    if (key == WXK_UP)
    {
      if (m_CommandsIterator != m_Commands.begin())
      {
        m_CommandsIterator--;
      }
    }
    else
    {
      if (m_CommandsIterator != m_Commands.end())
      {
        m_CommandsIterator++;
      }
    }

    if (m_CommandsIterator != m_Commands.end())
    {
      ReplaceTarget(m_Prompt + *m_CommandsIterator);
    }
    else
    {
      ReplaceTarget(m_Prompt);
    }

    DocumentEnd();
  }
}

void exSTCShell::ShowHistory()
{
  int command_no = 1;

  for (
    list < wxString >::iterator it = m_Commands.begin();
    it != m_Commands.end();
    it++)
  {
    AppendText(
      wxString::Format("\n%d %s",
        command_no++,
        wxString(*it).c_str()));
  }
}

#endif // wxUSE_GUI
<|endoftext|>


<commit_before>/******************************************************************************\
* File:          test.cpp
* Purpose:       Implementation for wxextension cpp unit testing
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id$
* Created:       za 17 jan 2009 11:51:20 CET
*
* Copyright (c) 2009 Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <TestCaller.h>
#include "test.h"

void exTestFixture::setUp()
{
  m_File = new exFile("test.h");
  m_FileName = new exFileName("test.h");
  m_FileNameStatistics = new exFileNameStatistics("test.h");
  m_Lexer = new exLexer();
  m_RCS = new exRCS();
  m_Stat = new exStat("test.h");
  m_Statistics = new exStatistics<long>();
  m_Tool = new exTool(ID_TOOL_REPORT_COUNT);
}

void exTestFixture::testConstructors()
{
  CPPUNIT_ASSERT(m_File != NULL);
}

void exTestFixture::testMethods()
{
  // test exFile
  CPPUNIT_ASSERT(m_File->GetStat().IsOk());
  CPPUNIT_ASSERT(m_File->GetFileName().GetFullPath() == "test.h");

  // test exFileName
  CPPUNIT_ASSERT(m_FileName->GetStat().IsOk());

  // test exLexer
  m_Lexer->SetLexerFromText("// this is a cpp comment text");
  CPPUNIT_ASSERT(m_Lexer->GetScintillaLexer().empty()); // we have no lexers

  // test exRCS
  CPPUNIT_ASSERT(m_RCS->GetUser().empty());

  // test exStat
  CPPUNIT_ASSERT(!m_Stat->IsLink());
  CPPUNIT_ASSERT(m_Stat->IsOk());
  CPPUNIT_ASSERT(!m_Stat->IsReadOnly());

  // test exStatistics
  m_Statistics->Inc("test");
  CPPUNIT_ASSERT(m_Statistics->Get("test") == 1);
  m_Statistics->Inc("test");
  CPPUNIT_ASSERT(m_Statistics->Get("test") == 2);
  m_Statistics->Set("test", 13);
  CPPUNIT_ASSERT(m_Statistics->Get("test") == 13);
  m_Statistics->Dec("test");
  CPPUNIT_ASSERT(m_Statistics->Get("test") == 12);
  m_Statistics->Inc("test2");
  CPPUNIT_ASSERT(m_Statistics->Get("test2") == 1);
  m_Statistics->Clear();
  CPPUNIT_ASSERT(m_Statistics->GetItems().empty());

  // test exTool
  CPPUNIT_ASSERT(m_Tool->IsStatisticsType() > 0);
}

void exTestFixture::testTiming()
{
  exFile file("test.h");

  CPPUNIT_ASSERT(file.IsOpened());

  wxStopWatch sw;

  const int max = 10000;

  for (int i = 0; i < max; i++)
  {
    wxString* buffer = file.Read();
    CPPUNIT_ASSERT(buffer != NULL);
    delete buffer;
  }

  const long exfile_read = sw.Time();

  sw.Start();

  wxFile wxfile("test.h");

  for (int j = 0; j < max; j++)
  {
    char* charbuffer = new char[wxfile.Length()];
    wxfile.Read(charbuffer, wxfile.Length());
    wxString* buffer = new wxString(charbuffer, wxfile.Length());
    delete charbuffer;
    delete buffer;
  }

  const long file_read = sw.Time();

  printf(
    "exFile::Read:%ld wxFile::Read:%ld\n",
    exfile_read,
    file_read);
}

void exTestFixture::testTimingAttrib()
{
  const int max = 1000;

  wxStopWatch sw;

  const exFileName exfile("test.h");

  int checked = 0;

  for (int i = 0; i < max; i++)
  {
    checked += exfile.GetStat().IsReadOnly();
  }

  const long exfile_time = sw.Time();

  sw.Start();

  const wxFileName file("test.h");

  for (int j = 0; j < max; j++)
  {
    checked += file.IsFileWritable();
  }

  const long file_time = sw.Time();

  printf(
    "exFileName::IsReadOnly:%ld wxFileName::IsFileWritable:%ld\n",
    exfile_time,
    file_time);
}

void exTestFixture::tearDown()
{
}

void exAppTestFixture::setUp()
{
}

void exAppTestFixture::testConstructors()
{
  m_App = new exApp();
  m_Dir = new exDir("./");
  m_SVN = new exSVN(SVN_STAT, "test.h");
}

void exAppTestFixture::testMethods()
{
  // test exApp
  m_App->OnInit();

  CPPUNIT_ASSERT(m_App->GetConfig() != NULL);
  CPPUNIT_ASSERT(m_App->GetLexers() != NULL);
  CPPUNIT_ASSERT(m_App->GetPrinter() != NULL);

  // test exDir
  CPPUNIT_ASSERT(m_Dir->GetFiles().GetCount() > 0);

  // test exSVN
  m_SVN->Get();
}

void exAppTestFixture::testTimingConfig()
{
  const int max = 100000;

  wxStopWatch sw;

  for (int i = 0; i < max; i++)
  {
    exApp::GetConfig("test", 0);
  }

  const long exconfig = sw.Time();

  sw.Start();

  for (int j = 0; j < max; j++)
  {
    exApp::GetConfig()->Read("test", 0l);
  }

  const long config = sw.Time();

  printf(
    "exConfig::Get:%ld wxConfig::Read:%ld\n",
    exconfig,
    config);
}

void exAppTestFixture::tearDown()
{
}

exTestSuite::exTestSuite()
  : CppUnit::TestSuite("wxextension test suite")

{
  // Add the tests.
  addTest(new CppUnit::TestCaller<exTestFixture>(
    "testConstructors",
    &exTestFixture::testConstructors));

  addTest(new CppUnit::TestCaller<exTestFixture>(
    "testMethods",
    &exTestFixture::testMethods));

  addTest(new CppUnit::TestCaller<exTestFixture>(
    "testTiming",
    &exTestFixture::testTiming));

  addTest(new CppUnit::TestCaller<exTestFixture>(
    "testTimingAttrib",
    &exTestFixture::testTimingAttrib));

/* TODO: the exApp or wxApp not yet okay without normal wxApp initialization

  addTest(new CppUnit::TestCaller<exAppTestFixture>(
    "testConstructors",
    &exAppTestFixture::testConstructors));

  addTest(new CppUnit::TestCaller<exAppTestFixture>(
    "testMethods",
    &exAppTestFixture::testMethods));

  addTest(new CppUnit::TestCaller<exAppTestFixture>(
    "testTimingConfig",
    &exAppTestFixture::testTimingConfig));
    */
}
<commit_msg>more exSVN tests<commit_after>/******************************************************************************\
* File:          test.cpp
* Purpose:       Implementation for wxextension cpp unit testing
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id$
* Created:       za 17 jan 2009 11:51:20 CET
*
* Copyright (c) 2009 Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <TestCaller.h>
#include "test.h"

void exTestFixture::setUp()
{
  m_File = new exFile("test.h");
  m_FileName = new exFileName("test.h");
  m_FileNameStatistics = new exFileNameStatistics("test.h");
  m_Lexer = new exLexer();
  m_RCS = new exRCS();
  m_Stat = new exStat("test.h");
  m_Statistics = new exStatistics<long>();
  m_Tool = new exTool(ID_TOOL_REPORT_COUNT);
}

void exTestFixture::testConstructors()
{
  CPPUNIT_ASSERT(m_File != NULL);
}

void exTestFixture::testMethods()
{
  // test exFile
  CPPUNIT_ASSERT(m_File->GetStat().IsOk());
  CPPUNIT_ASSERT(m_File->GetFileName().GetFullPath() == "test.h");

  // test exFileName
  CPPUNIT_ASSERT(m_FileName->GetStat().IsOk());

  // test exLexer
  m_Lexer->SetLexerFromText("// this is a cpp comment text");
  CPPUNIT_ASSERT(m_Lexer->GetScintillaLexer().empty()); // we have no lexers

  // test exRCS
  CPPUNIT_ASSERT(m_RCS->GetUser().empty());

  // test exStat
  CPPUNIT_ASSERT(!m_Stat->IsLink());
  CPPUNIT_ASSERT(m_Stat->IsOk());
  CPPUNIT_ASSERT(!m_Stat->IsReadOnly());

  // test exStatistics
  m_Statistics->Inc("test");
  CPPUNIT_ASSERT(m_Statistics->Get("test") == 1);
  m_Statistics->Inc("test");
  CPPUNIT_ASSERT(m_Statistics->Get("test") == 2);
  m_Statistics->Set("test", 13);
  CPPUNIT_ASSERT(m_Statistics->Get("test") == 13);
  m_Statistics->Dec("test");
  CPPUNIT_ASSERT(m_Statistics->Get("test") == 12);
  m_Statistics->Inc("test2");
  CPPUNIT_ASSERT(m_Statistics->Get("test2") == 1);
  m_Statistics->Clear();
  CPPUNIT_ASSERT(m_Statistics->GetItems().empty());

  // test exTool
  CPPUNIT_ASSERT(m_Tool->IsStatisticsType() > 0);
}

void exTestFixture::testTiming()
{
  exFile file("test.h");

  CPPUNIT_ASSERT(file.IsOpened());

  wxStopWatch sw;

  const int max = 10000;

  for (int i = 0; i < max; i++)
  {
    wxString* buffer = file.Read();
    CPPUNIT_ASSERT(buffer != NULL);
    delete buffer;
  }

  const long exfile_read = sw.Time();

  sw.Start();

  wxFile wxfile("test.h");

  for (int j = 0; j < max; j++)
  {
    char* charbuffer = new char[wxfile.Length()];
    wxfile.Read(charbuffer, wxfile.Length());
    wxString* buffer = new wxString(charbuffer, wxfile.Length());
    delete charbuffer;
    delete buffer;
  }

  const long file_read = sw.Time();

  printf(
    "exFile::Read:%ld wxFile::Read:%ld\n",
    exfile_read,
    file_read);
}

void exTestFixture::testTimingAttrib()
{
  const int max = 1000;

  wxStopWatch sw;

  const exFileName exfile("test.h");

  int checked = 0;

  for (int i = 0; i < max; i++)
  {
    checked += exfile.GetStat().IsReadOnly();
  }

  const long exfile_time = sw.Time();

  sw.Start();

  const wxFileName file("test.h");

  for (int j = 0; j < max; j++)
  {
    checked += file.IsFileWritable();
  }

  const long file_time = sw.Time();

  printf(
    "exFileName::IsReadOnly:%ld wxFileName::IsFileWritable:%ld\n",
    exfile_time,
    file_time);
}

void exTestFixture::tearDown()
{
}

void exAppTestFixture::setUp()
{
}

void exAppTestFixture::testConstructors()
{
  m_App = new exApp();
  m_Dir = new exDir("./");
  m_SVN = new exSVN(SVN_STAT, "test.h");
}

void exAppTestFixture::testMethods()
{
  // test exApp
  m_App->OnInit();

  CPPUNIT_ASSERT(m_App->GetConfig() != NULL);
  CPPUNIT_ASSERT(m_App->GetLexers() != NULL);
  CPPUNIT_ASSERT(m_App->GetPrinter() != NULL);

  // test exDir
  CPPUNIT_ASSERT(m_Dir->GetFiles().GetCount() > 0);

  // test exSVN
  CPPUNIT_ASSERT(m_SVN->GetInfo() == 0);
  CPPUNIT_ASSERT(!m_SVN->GetContents().empty());
}

void exAppTestFixture::testTimingConfig()
{
  const int max = 100000;

  wxStopWatch sw;

  for (int i = 0; i < max; i++)
  {
    exApp::GetConfig("test", 0);
  }

  const long exconfig = sw.Time();

  sw.Start();

  for (int j = 0; j < max; j++)
  {
    exApp::GetConfig()->Read("test", 0l);
  }

  const long config = sw.Time();

  printf(
    "exConfig::Get:%ld wxConfig::Read:%ld\n",
    exconfig,
    config);
}

void exAppTestFixture::tearDown()
{
}

exTestSuite::exTestSuite()
  : CppUnit::TestSuite("wxextension test suite")

{
  // Add the tests.
  addTest(new CppUnit::TestCaller<exTestFixture>(
    "testConstructors",
    &exTestFixture::testConstructors));

  addTest(new CppUnit::TestCaller<exTestFixture>(
    "testMethods",
    &exTestFixture::testMethods));

  addTest(new CppUnit::TestCaller<exTestFixture>(
    "testTiming",
    &exTestFixture::testTiming));

  addTest(new CppUnit::TestCaller<exTestFixture>(
    "testTimingAttrib",
    &exTestFixture::testTimingAttrib));

/* TODO: the exApp or wxApp not yet okay without normal wxApp initialization

  addTest(new CppUnit::TestCaller<exAppTestFixture>(
    "testConstructors",
    &exAppTestFixture::testConstructors));

  addTest(new CppUnit::TestCaller<exAppTestFixture>(
    "testMethods",
    &exAppTestFixture::testMethods));

  addTest(new CppUnit::TestCaller<exAppTestFixture>(
    "testTimingConfig",
    &exAppTestFixture::testTimingConfig));
    */
}
<|endoftext|>


<commit_before>/*
The MIT License (MIT)

Copyright (c) 2014

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include "cppparser.h"
#include "compare.h"
#include "cppwriter.h"
#include "options.h"

#include <fstream>
#include <iostream>
#include <utility>

#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>
#include <boost/system/config.hpp>

namespace bfs = boost::filesystem;
namespace bpo = boost::program_options;

//////////////////////////////////////////////////////////////////////////

static bool parseAndEmitFormatted(CppParser&       parser,
                                  const bfs::path& inputFilePath,
                                  const bfs::path& outputFilePath,
                                  const CppWriter& cppWriter)
{
  auto progUnit = parser.parseFile(inputFilePath.string().c_str());
  if (!progUnit)
    return false;
  bfs::create_directories(outputFilePath.parent_path());
  std::ofstream stm(outputFilePath.string());
  cppWriter.emit(progUnit.get(), stm);

  return true;
}

static bool performParsing(CppParser& parser, const std::string& inputPath)
{
  auto progUnit = parser.parseFile(inputPath.c_str());
  if (!progUnit)
    return false;

  return true;
}

static std::pair<size_t, size_t> performTest(CppParser& parser, const TestParam& params)
{
  size_t numInputFiles = 0;
  size_t numFailed     = 0;

  using FilePair                        = std::pair<std::string, std::string>;
  auto                     inputPathLen = params.inputPath.string().length();
  std::vector<std::string> parsingFailedFor;
  std::vector<FilePair>    diffFailedList;

  for (bfs::recursive_directory_iterator dirItr(params.inputPath); dirItr != bfs::recursive_directory_iterator();
       ++dirItr)
  {
    CppWriter cppWriter;
    bfs::path file = *dirItr;
    if (bfs::is_regular_file(file))
    {
      ++numInputFiles;
      std::cout << "CppParserTest: Parsing " << file.string() << " ...\n";
      auto      fileRelPath = file.string().substr(inputPathLen);
      bfs::path outfile     = params.outputPath / fileRelPath;
      bfs::remove(outfile);
      if (parseAndEmitFormatted(parser, file, outfile, cppWriter) && bfs::exists(outfile))
      {
        bfs::path           masfile = params.masterPath / fileRelPath;
        std::pair<int, int> diffStartInfo;
        auto                rez = compareFiles(outfile, masfile, diffStartInfo);
        if (rez == kSameFiles)
          continue;
        reportFileComparisonError(rez, outfile, masfile, diffStartInfo);
        diffFailedList.emplace_back(std::make_pair(outfile.string(), masfile.string()));
      }
      else
      {
        auto filePathStr = file.string();
        std::cerr << "Parsing failed for " << filePathStr << "\n";
        parsingFailedFor.push_back(filePathStr);
      }
      ++numFailed;
    }
  }
  if (!diffFailedList.empty())
  {
    std::cerr << "\n\n";
    std::cerr << "Comparision failure summary.\n------------------------\n";
    for (const auto& itr : diffFailedList)
    {
      std::cerr << itr.first << ' ' << itr.second << '\n';
    }
    std::cerr << "Comparision failed for " << diffFailedList.size() << " files.\n\n";
  }
  if (!parsingFailedFor.empty())
  {
    std::cerr << "\n\n";
    std::cerr << "Parsing failure summary.\n------------------------\n";
    for (const auto& s : parsingFailedFor)
    {
      std::cerr << s << '\n';
    }
    std::cerr << "Parsing failed for " << parsingFailedFor.size() << " files.\n\n";
  }

  return std::make_pair(numInputFiles, numFailed);
}

CppParser constructCppParserForTest()
{
  CppParser parser;
  parser.addKnownApiDecors({"ODRX_ABSTRACT",
                            "FIRSTDLL_EXPORT",
                            "GE_DLLEXPIMPORT",
                            "TOOLKIT_EXPORT",

                            "APIENTRY",
                            "WINGDIAPI",
                            "GLUTAPI",

                            "ADESK_NO_VTABLE",
                            "ACDBCORE2D_PORT",
                            "ACBASE_PORT",
                            "ACCORE_PORT",
                            "ACDB_PORT",
                            "ACPAL_PORT",
                            "ACAD_PORT",
                            "ACPL_PORT",
                            "ACTCUI_PORT",
                            "ADESK_DEPRECATED",
                            "DRAWBRIDGE_API",
                            "AXAUTOEXP",
                            "GX_DLLEXPIMPORT",
                            "ANAV_PORT",
                            "DRAWBRIDGE_MAC_API",
                            "ADUI_PORT",
                            "ACMPOLYGON_PORT",
                            "ACFDUI_PORT",
                            "GE_DLLDATAEXIMP",
                            "ACSYNERGY_PORT",
                            "ADESK_STDCALL",
                            "LIGHTDLLIMPEXP",
                            "SCENEDLLIMPEXP",
                            "DLLScope",

                            "_CRTIMP",

                            "SKSL_WARN_UNUSED_RESULT",
                            "SK_ALWAYS_INLINE",
                            "SK_API",
                            "SK_BEGIN_REQUIRE_DENSE",
                            "SK_WARN_UNUSED_RESULT",
                            "SK_CAPABILITY",

                            "PODOFO_DEPRECATED",
                            "PODOFO_API"});

  parser.addKnownMacros({"DECLARE_MESSAGE_MAP",
                         "DECLARE_DYNAMIC",
                         "ACPL_DECLARE_MEMBERS",
                         "DBSYMUTL_MAKE_GETSYMBOLID_FUNCTION",
                         "DBSYMUTL_MAKE_HASSYMBOLID_FUNCTION",
                         "DBSYMUTL_MAKE_HASSYMBOLNAME_FUNCTION",
                         "ACRX_DECLARE_MEMBERS_EXPIMP",
                         "ACRX_DECLARE_MEMBERS_ACBASE_PORT_EXPIMP",
                         "ACRX_DECLARE_MEMBERS",
                         "DBCURVE_METHODS",

                         "SK_BEGIN_REQUIRE_DENSE",
                         "SK_END_REQUIRE_DENSE",
                         "GR_MAKE_BITFIELD_CLASS_OPS",
                         "SK_C_PLUS_PLUS_BEGIN_GUARD",
                         "SK_C_PLUS_PLUS_END_GUARD",
                         "GPU_DRIVER_BUG_WORKAROUNDS",
                         "GR_MAKE_BITFIELD_OPS",
                         "SK_FLATTENABLE_HOOKS",
                         "SK_USE_FLUENT_IMAGE_FILTER_TYPES_IN_CLASS",
                         "SK_RASTER_PIPELINE_STAGES",
                         "INTERNAL_DECLARE_SET_TRACE_VALUE_INT",
                         "INTERNAL_DECLARE_SET_TRACE_VALUE",
                         "SK_RECORD_TYPES",
                         "SK_OT_BYTE_BITFIELD",
                         "SKSL_PRINTF_LIKE",
                         "ACT_AS_PTR",
                         "RECORD",
                         "GR_DECLARE_FRAGMENT_PROCESSOR_TEST",
                         "GR_DECLARE_GEOMETRY_PROCESSOR_TEST",
                         "GR_DECLARE_XP_FACTORY_TEST",
                         "DEFINE_NAMED_APPEND",
                         "SK_CALLABLE_TRAITS__CV_REF_NE_VARARGS",
                         "SK_CALLABLE_TRAITS__NE_VARARGS",
                         "SK_STDMETHODIMP_",
                         "SK_END_REQUIRE_DENSE",
                         "GR_DECL_BITFIELD_OPS_FRIENDS",
                         "SK_PRINTF_LIKE",
                         "DEFINE_OP_CLASS_ID",
                         "SHARD",
                         "SK_WHEN",

                         "PODOFO_RAISE_LOGIC_IF"});

  parser.addIgnorableMacros({"SkDEBUGCODE",
                             "SkDEBUGPARAMS",
                             "__bridge",
                             "__bridge_retained",
                             "API_AVAILABLE",
                             "SK_RESTRICT",
                             "DEBUG_COIN_DECLARE_PARAMS",
                             "PATH_OPS_DEBUG_T_SECT_CODE",
                             "PATH_OPS_DEBUG_T_SECT_PARAMS",
                             "SK_GUARDED_BY",
                             "SK_ACQUIRE",
                             "SK_REQUIRES",
                             "SK_RELEASE_CAPABILITY",
                             "SK_ASSERT_CAPABILITY",
                             "SK_ACQUIRE_SHARED",
                             "SK_RELEASE_SHARED_CAPABILITY",
                             "SK_BLITBWMASK_ARGS",
                             "SK_ASSERT_SHARED_CAPABILITY",

                             "PODOFO_LOCAL",
                             "PDF_SIZE_FORMAT",

                             "WXUNUSED"});

  parser.addRenamedKeyword("virtual", "ADESK_SEALED_VIRTUAL");
  parser.addRenamedKeyword("final", "ADESK_SEALED");
  parser.addRenamedKeyword("override", "ADESK_OVERRIDE");

  return std::move(parser);
}

int main(int argc, char** argv)
{
  CppParser parser = constructCppParserForTest();
  parser.parseEnumBodyAsBlob();

  ArgParser argParser;
  auto      optionParseResult = argParser.parse(argc, argv);
  if (optionParseResult == ArgParser::kParsingError)
  {
    argParser.emitError();
    return -1;
  }
  else if (optionParseResult == ArgParser::kParseSingleFile)
  {
    auto filePath = argParser.extractSingleFilePath();
    performParsing(parser, filePath);
  }
  else
  {
    auto params = argParser.extractParamsForFullTest();
    auto result = performTest(parser, params);
    if (result.second)
    {
      std::cerr << "CppParserTest: " << result.second << " tests failed out of " << result.first << ".\n";
      return 1;
    }
    std::cout << "CppParserTest: All " << result.first << " tests passed without error.\n";
  }
  return 0; // All went well.
}
<commit_msg>Added parser options for wxWidgets test files<commit_after>/*
The MIT License (MIT)

Copyright (c) 2014

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include "cppparser.h"
#include "compare.h"
#include "cppwriter.h"
#include "options.h"

#include <fstream>
#include <iostream>
#include <utility>

#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>
#include <boost/system/config.hpp>

namespace bfs = boost::filesystem;
namespace bpo = boost::program_options;

//////////////////////////////////////////////////////////////////////////

static bool parseAndEmitFormatted(CppParser&       parser,
                                  const bfs::path& inputFilePath,
                                  const bfs::path& outputFilePath,
                                  const CppWriter& cppWriter)
{
  auto progUnit = parser.parseFile(inputFilePath.string().c_str());
  if (!progUnit)
    return false;
  bfs::create_directories(outputFilePath.parent_path());
  std::ofstream stm(outputFilePath.string());
  cppWriter.emit(progUnit.get(), stm);

  return true;
}

static bool performParsing(CppParser& parser, const std::string& inputPath)
{
  auto progUnit = parser.parseFile(inputPath.c_str());
  if (!progUnit)
    return false;

  return true;
}

static std::pair<size_t, size_t> performTest(CppParser& parser, const TestParam& params)
{
  size_t numInputFiles = 0;
  size_t numFailed     = 0;

  using FilePair                        = std::pair<std::string, std::string>;
  auto                     inputPathLen = params.inputPath.string().length();
  std::vector<std::string> parsingFailedFor;
  std::vector<FilePair>    diffFailedList;

  for (bfs::recursive_directory_iterator dirItr(params.inputPath); dirItr != bfs::recursive_directory_iterator();
       ++dirItr)
  {
    CppWriter cppWriter;
    bfs::path file = *dirItr;
    if (bfs::is_regular_file(file))
    {
      ++numInputFiles;
      std::cout << "CppParserTest: Parsing " << file.string() << " ...\n";
      auto      fileRelPath = file.string().substr(inputPathLen);
      bfs::path outfile     = params.outputPath / fileRelPath;
      bfs::remove(outfile);
      if (parseAndEmitFormatted(parser, file, outfile, cppWriter) && bfs::exists(outfile))
      {
        bfs::path           masfile = params.masterPath / fileRelPath;
        std::pair<int, int> diffStartInfo;
        auto                rez = compareFiles(outfile, masfile, diffStartInfo);
        if (rez == kSameFiles)
          continue;
        reportFileComparisonError(rez, outfile, masfile, diffStartInfo);
        diffFailedList.emplace_back(std::make_pair(outfile.string(), masfile.string()));
      }
      else
      {
        auto filePathStr = file.string();
        std::cerr << "Parsing failed for " << filePathStr << "\n";
        parsingFailedFor.push_back(filePathStr);
      }
      ++numFailed;
    }
  }
  if (!diffFailedList.empty())
  {
    std::cerr << "\n\n";
    std::cerr << "Comparision failure summary.\n------------------------\n";
    for (const auto& itr : diffFailedList)
    {
      std::cerr << itr.first << ' ' << itr.second << '\n';
    }
    std::cerr << "Comparision failed for " << diffFailedList.size() << " files.\n\n";
  }
  if (!parsingFailedFor.empty())
  {
    std::cerr << "\n\n";
    std::cerr << "Parsing failure summary.\n------------------------\n";
    for (const auto& s : parsingFailedFor)
    {
      std::cerr << s << '\n';
    }
    std::cerr << "Parsing failed for " << parsingFailedFor.size() << " files.\n\n";
  }

  return std::make_pair(numInputFiles, numFailed);
}

CppParser constructCppParserForTest()
{
  CppParser parser;
  parser.addKnownApiDecors({"ODRX_ABSTRACT",
                            "FIRSTDLL_EXPORT",
                            "GE_DLLEXPIMPORT",
                            "TOOLKIT_EXPORT",

                            "APIENTRY",
                            "WINGDIAPI",
                            "GLUTAPI",

                            "ADESK_NO_VTABLE",
                            "ACDBCORE2D_PORT",
                            "ACBASE_PORT",
                            "ACCORE_PORT",
                            "ACDB_PORT",
                            "ACPAL_PORT",
                            "ACAD_PORT",
                            "ACPL_PORT",
                            "ACTCUI_PORT",
                            "ADESK_DEPRECATED",
                            "DRAWBRIDGE_API",
                            "AXAUTOEXP",
                            "GX_DLLEXPIMPORT",
                            "ANAV_PORT",
                            "DRAWBRIDGE_MAC_API",
                            "ADUI_PORT",
                            "ACMPOLYGON_PORT",
                            "ACFDUI_PORT",
                            "GE_DLLDATAEXIMP",
                            "ACSYNERGY_PORT",
                            "ADESK_STDCALL",
                            "LIGHTDLLIMPEXP",
                            "SCENEDLLIMPEXP",
                            "DLLScope",

                            "_CRTIMP",

                            "SKSL_WARN_UNUSED_RESULT",
                            "SK_ALWAYS_INLINE",
                            "SK_API",
                            "SK_BEGIN_REQUIRE_DENSE",
                            "SK_WARN_UNUSED_RESULT",
                            "SK_CAPABILITY",

                            "PODOFO_DEPRECATED",
                            "PODOFO_API",

                            "WXDLLIMPEXP_ADV",
                            "WXDLLIMPEXP_BASE",
                            "WXDLLIMPEXP_CORE",
                            "WXDLLIMPEXP_HTML",
                            "WXDLLIMPEXP_NET",
                            "WXDLLIMPEXP_PROPGRID",
                            "WXDLLIMPEXP_QA",
                            "WXDLLIMPEXP_STC",
                            "WXDLLIMPEXP_WEBVIEW",
                            "wxDEPRECATED_MSG",
                            "wxDEPRECATED_CLASS_MSG"});

  parser.addKnownMacros({"DECLARE_MESSAGE_MAP",
                         "DECLARE_DYNAMIC",
                         "ACPL_DECLARE_MEMBERS",
                         "DBSYMUTL_MAKE_GETSYMBOLID_FUNCTION",
                         "DBSYMUTL_MAKE_HASSYMBOLID_FUNCTION",
                         "DBSYMUTL_MAKE_HASSYMBOLNAME_FUNCTION",
                         "ACRX_DECLARE_MEMBERS_EXPIMP",
                         "ACRX_DECLARE_MEMBERS_ACBASE_PORT_EXPIMP",
                         "ACRX_DECLARE_MEMBERS",
                         "DBCURVE_METHODS",

                         "SK_BEGIN_REQUIRE_DENSE",
                         "SK_END_REQUIRE_DENSE",
                         "GR_MAKE_BITFIELD_CLASS_OPS",
                         "SK_C_PLUS_PLUS_BEGIN_GUARD",
                         "SK_C_PLUS_PLUS_END_GUARD",
                         "GPU_DRIVER_BUG_WORKAROUNDS",
                         "GR_MAKE_BITFIELD_OPS",
                         "SK_FLATTENABLE_HOOKS",
                         "SK_USE_FLUENT_IMAGE_FILTER_TYPES_IN_CLASS",
                         "SK_RASTER_PIPELINE_STAGES",
                         "INTERNAL_DECLARE_SET_TRACE_VALUE_INT",
                         "INTERNAL_DECLARE_SET_TRACE_VALUE",
                         "SK_RECORD_TYPES",
                         "SK_OT_BYTE_BITFIELD",
                         "SKSL_PRINTF_LIKE",
                         "ACT_AS_PTR",
                         "RECORD",
                         "GR_DECLARE_FRAGMENT_PROCESSOR_TEST",
                         "GR_DECLARE_GEOMETRY_PROCESSOR_TEST",
                         "GR_DECLARE_XP_FACTORY_TEST",
                         "DEFINE_NAMED_APPEND",
                         "SK_CALLABLE_TRAITS__CV_REF_NE_VARARGS",
                         "SK_CALLABLE_TRAITS__NE_VARARGS",
                         "SK_STDMETHODIMP_",
                         "SK_END_REQUIRE_DENSE",
                         "GR_DECL_BITFIELD_OPS_FRIENDS",
                         "SK_PRINTF_LIKE",
                         "DEFINE_OP_CLASS_ID",
                         "SHARD",
                         "SK_WHEN",

                         "PODOFO_RAISE_LOGIC_IF",

                         "WX_DECLARE_USER_EXPORTED_BASEARRAY",
                         "WX_DEFINE_USER_EXPORTED_ARRAY_SHORT",
                         "WX_DEFINE_USER_EXPORTED_ARRAY_INT",
                         "WX_DEFINE_USER_EXPORTED_ARRAY_DOUBLE",
                         "WX_DEFINE_USER_EXPORTED_ARRAY_LONG",
                         "WX_DEFINE_USER_EXPORTED_ARRAY_PTR",
                         "WX_DEFINE_SORTED_EXPORTED_ARRAY_CMP_INT"});

  parser.addIgnorableMacros({"SkDEBUGCODE",
                             "SkDEBUGPARAMS",
                             "__bridge",
                             "__bridge_retained",
                             "API_AVAILABLE",
                             "SK_RESTRICT",
                             "DEBUG_COIN_DECLARE_PARAMS",
                             "PATH_OPS_DEBUG_T_SECT_CODE",
                             "PATH_OPS_DEBUG_T_SECT_PARAMS",
                             "SK_GUARDED_BY",
                             "SK_ACQUIRE",
                             "SK_REQUIRES",
                             "SK_RELEASE_CAPABILITY",
                             "SK_ASSERT_CAPABILITY",
                             "SK_ACQUIRE_SHARED",
                             "SK_RELEASE_SHARED_CAPABILITY",
                             "SK_BLITBWMASK_ARGS",
                             "SK_ASSERT_SHARED_CAPABILITY",

                             "PODOFO_LOCAL",
                             "PDF_SIZE_FORMAT",

                             "WXUNUSED",
                             "WXDLLIMPEXP_DATA_CORE",
                             "wxDEPRECATED_BUT_USED_INTERNALLY_INLINE"});

  parser.addRenamedKeyword("virtual", "ADESK_SEALED_VIRTUAL");
  parser.addRenamedKeyword("final", "ADESK_SEALED");
  parser.addRenamedKeyword("override", "ADESK_OVERRIDE");
  parser.addRenamedKeyword("override", "wxOVERRIDE");

  return std::move(parser);
}

int main(int argc, char** argv)
{
  CppParser parser = constructCppParserForTest();
  parser.parseEnumBodyAsBlob();

  ArgParser argParser;
  auto      optionParseResult = argParser.parse(argc, argv);
  if (optionParseResult == ArgParser::kParsingError)
  {
    argParser.emitError();
    return -1;
  }
  else if (optionParseResult == ArgParser::kParseSingleFile)
  {
    auto filePath = argParser.extractSingleFilePath();
    performParsing(parser, filePath);
  }
  else
  {
    auto params = argParser.extractParamsForFullTest();
    auto result = performTest(parser, params);
    if (result.second)
    {
      std::cerr << "CppParserTest: " << result.second << " tests failed out of " << result.first << ".\n";
      return 1;
    }
    std::cout << "CppParserTest: All " << result.first << " tests passed without error.\n";
  }
  return 0; // All went well.
}
<|endoftext|>


<commit_before>/*!
  \copyright (c) RDO-Team, 2012
  \file      animation_sprite.h
  \author      (rdo@rk9.bmstu.ru)
  \date      14.12.2012
  \brief
  \indent    4T
*/

// ---------------------------------------------------------------------------- PCH
#include "simulator/compiler/parser/pch.h"
// ----------------------------------------------------------------------- INCLUDES
// ----------------------------------------------------------------------- SYNOPSIS
#include "simulator/compiler/parser/src/animation/animation_frame.h"
#include "simulator/compiler/parser/rdoparser.h"
// --------------------------------------------------------------------------------

OPEN_RDO_PARSER_NAMESPACE

RDOFRMSprite::RDOFRMSprite(CREF(RDOParserSrcInfo) src_info)
	: RDOFRMCommandList()
{
	m_pFunction = rdo::Factory<Function>::create(
		rdo::Factory<TypeInfo>::delegate<RDOType__void>(src_info),
		src_info
	);
	ASSERT(m_pFunction);

	m_pSprite = rdo::Factory<rdo::runtime::RDOFRMSprite>::create(m_pFunction->src_info());
	ASSERT(m_pSprite)

	RDOParser::s_parser()->insertFRMSprite(this);

	m_pFunction->pushContext();
}

RDOFRMSprite::~RDOFRMSprite()
{
	m_pFunction->popContext();
}

CREF(tstring) RDOFRMSprite::name() const
{
	return m_pFunction->src_text();
}

rdo::runtime::LPRDOFRMSprite RDOFRMSprite::list() const
{
	return m_pSprite;
}

LPExpression RDOFRMSprite::expression() const
{
	return m_pFunction->expression();
}

void RDOFRMSprite::end()
{
	m_pSprite->setSpriteCalc(expression()->calc());
}

CLOSE_RDO_PARSER_NAMESPACE
<commit_msg> - лучше удалить контекст из end()<commit_after>/*!
  \copyright (c) RDO-Team, 2012
  \file      animation_sprite.h
  \author      (rdo@rk9.bmstu.ru)
  \date      14.12.2012
  \brief
  \indent    4T
*/

// ---------------------------------------------------------------------------- PCH
#include "simulator/compiler/parser/pch.h"
// ----------------------------------------------------------------------- INCLUDES
// ----------------------------------------------------------------------- SYNOPSIS
#include "simulator/compiler/parser/src/animation/animation_frame.h"
#include "simulator/compiler/parser/rdoparser.h"
// --------------------------------------------------------------------------------

OPEN_RDO_PARSER_NAMESPACE

RDOFRMSprite::RDOFRMSprite(CREF(RDOParserSrcInfo) src_info)
	: RDOFRMCommandList()
{
	m_pFunction = rdo::Factory<Function>::create(
		rdo::Factory<TypeInfo>::delegate<RDOType__void>(src_info),
		src_info
	);
	ASSERT(m_pFunction);

	m_pSprite = rdo::Factory<rdo::runtime::RDOFRMSprite>::create(m_pFunction->src_info());
	ASSERT(m_pSprite)

	RDOParser::s_parser()->insertFRMSprite(this);

	m_pFunction->pushContext();
}

RDOFRMSprite::~RDOFRMSprite()
{}

CREF(tstring) RDOFRMSprite::name() const
{
	return m_pFunction->src_text();
}

rdo::runtime::LPRDOFRMSprite RDOFRMSprite::list() const
{
	return m_pSprite;
}

LPExpression RDOFRMSprite::expression() const
{
	return m_pFunction->expression();
}

void RDOFRMSprite::end()
{
	m_pFunction->popContext();
	m_pSprite->setSpriteCalc(expression()->calc());
}

CLOSE_RDO_PARSER_NAMESPACE
<|endoftext|>


<commit_before><commit_msg>Fixed wrong location of r_root_dh_frame<commit_after><|endoftext|>


<commit_before>/*=============================================================================

  Library: CTK

  Copyright (c) German Cancer Research Center,
    Division of Medical and Biological Informatics

  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.

=============================================================================*/

// Qt includes
#include <QApplication>
#include <QDebug>
#include <QFile>
#include <QBuffer>
#include <QWidget>
#include <QProcess>

#include <QDebug>

#include <QtXmlPatterns/QXmlQuery>
#include <QtUiTools/QUiLoader>

// CTK includes
#include <ctkCommandLineParser.h>
#include <ctkCmdLineModuleXmlValidator.h>

#include "ctkCmdLineModuleExplorerMainWindow.h"

int main(int argc, char** argv)
{
  QApplication myApp(argc, argv);
  myApp.setOrganizationName("CommonTK");
  myApp.setApplicationName("CommandLineModuleExplorer");

  ctkCommandLineParser cmdLineParser;
  cmdLineParser.setArgumentPrefix("--", "-");
  cmdLineParser.setStrictModeEnabled(true);

  cmdLineParser.addArgument("module", "", QVariant::String, "Path to a CLI module (executable)");
  //cmdLineParser.addArgument("module-xml", "", QVariant::String, "Path to a CLI XML description.");

  cmdLineParser.addArgument("validate-module", "", QVariant::String, "Path to a CLI module");
  cmdLineParser.addArgument("validate-xml", "", QVariant::String, "Path to a CLI XML description.");
  cmdLineParser.addArgument("verbose", "v", QVariant::Bool, "Be verbose.");
  cmdLineParser.addArgument("help", "h", QVariant::Bool, "Print this help text.");

  bool parseOkay = false;
  QHash<QString, QVariant> args = cmdLineParser.parseArguments(argc, argv, &parseOkay);

  QTextStream out(stdout, QIODevice::WriteOnly);

  if(!parseOkay)
  {
    out << "Error parsing command line arguments: " << cmdLineParser.errorString() << '\n';
    return EXIT_FAILURE;
  }

  if (args.contains("help"))
  {
    out << "Usage:\n" << cmdLineParser.helpText();
    out.flush();
    return EXIT_SUCCESS;
  }

  if (args.contains("validate-module"))
  {
    if (args.contains("validate-xml"))
    {
      out << "Ignoring \"validate-xml\" option.\n\n";
    }

    QString input = args["validate-module"].toString();
    if (!QFile::exists(input))
    {
      qCritical() << "Module does not exist:" << input;
      return EXIT_FAILURE;
    }

    QProcess process;
    process.setReadChannel(QProcess::StandardOutput);
    process.start(input, QStringList("--xml"));

    if (!process.waitForFinished() || process.exitStatus() == QProcess::CrashExit ||
        process.error() != QProcess::UnknownError)
    {
      qWarning() << "The executable at" << input << "could not be started:" << process.errorString();
      return EXIT_FAILURE;
    }

    process.waitForReadyRead();
    QByteArray xml = process.readAllStandardOutput();

    if (args.contains("verbose"))
    {
      qDebug() << xml;
    }

    // validate the outputted xml description
    QBuffer xmlInput(&xml);
    xmlInput.open(QIODevice::ReadOnly);

    ctkCmdLineModuleXmlValidator validator(&xmlInput);
    if (!validator.validateInput())
    {
      qCritical() << validator.errorString();
      return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
  }
  else if (args.contains("validate-xml"))
  {
    QFile input(args["validate-xml"].toString());
    if (!input.exists())
    {
      qCritical() << "XML description does not exist:" << input.fileName();
      return EXIT_FAILURE;
    }
    input.open(QIODevice::ReadOnly);

    ctkCmdLineModuleXmlValidator validator(&input);
    if (!validator.validateInput())
    {
      qCritical() << validator.errorString();
      return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
  }

  //ctkCmdLineModuleDescription* descr = ctkCmdLineModuleDescription::parse(&input);

  ctkCLModuleExplorerMainWindow mainWindow;

  if (args.contains("module"))
  {
    mainWindow.addModule(args["module"].toString());
  }

  mainWindow.show();

  return myApp.exec();
}
<commit_msg>Fix for #325 to build on mac<commit_after>/*=============================================================================

  Library: CTK

  Copyright (c) German Cancer Research Center,
    Division of Medical and Biological Informatics

  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.

=============================================================================*/

// Qt includes
#include <QApplication>
#include <QDebug>
#include <QFile>
#include <QBuffer>
#include <QWidget>
#include <QProcess>

#include <QDebug>

#include <QXmlQuery>
#include <QUiLoader>

// CTK includes
#include <ctkCommandLineParser.h>
#include <ctkCmdLineModuleXmlValidator.h>

#include "ctkCmdLineModuleExplorerMainWindow.h"

int main(int argc, char** argv)
{
  QApplication myApp(argc, argv);
  myApp.setOrganizationName("CommonTK");
  myApp.setApplicationName("CommandLineModuleExplorer");

  ctkCommandLineParser cmdLineParser;
  cmdLineParser.setArgumentPrefix("--", "-");
  cmdLineParser.setStrictModeEnabled(true);

  cmdLineParser.addArgument("module", "", QVariant::String, "Path to a CLI module (executable)");
  //cmdLineParser.addArgument("module-xml", "", QVariant::String, "Path to a CLI XML description.");

  cmdLineParser.addArgument("validate-module", "", QVariant::String, "Path to a CLI module");
  cmdLineParser.addArgument("validate-xml", "", QVariant::String, "Path to a CLI XML description.");
  cmdLineParser.addArgument("verbose", "v", QVariant::Bool, "Be verbose.");
  cmdLineParser.addArgument("help", "h", QVariant::Bool, "Print this help text.");

  bool parseOkay = false;
  QHash<QString, QVariant> args = cmdLineParser.parseArguments(argc, argv, &parseOkay);

  QTextStream out(stdout, QIODevice::WriteOnly);

  if(!parseOkay)
  {
    out << "Error parsing command line arguments: " << cmdLineParser.errorString() << '\n';
    return EXIT_FAILURE;
  }

  if (args.contains("help"))
  {
    out << "Usage:\n" << cmdLineParser.helpText();
    out.flush();
    return EXIT_SUCCESS;
  }

  if (args.contains("validate-module"))
  {
    if (args.contains("validate-xml"))
    {
      out << "Ignoring \"validate-xml\" option.\n\n";
    }

    QString input = args["validate-module"].toString();
    if (!QFile::exists(input))
    {
      qCritical() << "Module does not exist:" << input;
      return EXIT_FAILURE;
    }

    QProcess process;
    process.setReadChannel(QProcess::StandardOutput);
    process.start(input, QStringList("--xml"));

    if (!process.waitForFinished() || process.exitStatus() == QProcess::CrashExit ||
        process.error() != QProcess::UnknownError)
    {
      qWarning() << "The executable at" << input << "could not be started:" << process.errorString();
      return EXIT_FAILURE;
    }

    process.waitForReadyRead();
    QByteArray xml = process.readAllStandardOutput();

    if (args.contains("verbose"))
    {
      qDebug() << xml;
    }

    // validate the outputted xml description
    QBuffer xmlInput(&xml);
    xmlInput.open(QIODevice::ReadOnly);

    ctkCmdLineModuleXmlValidator validator(&xmlInput);
    if (!validator.validateInput())
    {
      qCritical() << validator.errorString();
      return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
  }
  else if (args.contains("validate-xml"))
  {
    QFile input(args["validate-xml"].toString());
    if (!input.exists())
    {
      qCritical() << "XML description does not exist:" << input.fileName();
      return EXIT_FAILURE;
    }
    input.open(QIODevice::ReadOnly);

    ctkCmdLineModuleXmlValidator validator(&input);
    if (!validator.validateInput())
    {
      qCritical() << validator.errorString();
      return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
  }

  //ctkCmdLineModuleDescription* descr = ctkCmdLineModuleDescription::parse(&input);

  ctkCLModuleExplorerMainWindow mainWindow;

  if (args.contains("module"))
  {
    mainWindow.addModule(args["module"].toString());
  }

  mainWindow.show();

  return myApp.exec();
}
<|endoftext|>


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

#include <cstddef>

#include <type_traits>

#include <utility>

#include "meta.hpp"

namespace generic
{

// min, max
template <typename T>
constexpr inline T const& max(T const& a, T const& b) noexcept
{
  return a > b ? a : b;
}

template <typename T>
constexpr inline T const& min(T const& a, T const& b) noexcept
{
  return a < b ? a : b;
}

template <typename T, typename ...A>
constexpr inline ::std::enable_if_t<
  bool(sizeof...(A)) &&
  all_of<
    ::std::is_same<
      typename ::std::decay<T>::type,
      typename ::std::decay<A>::type
    >...
  >{},
  T
>
max(T const& a, T const& b, A&& ...args) noexcept
{
  return a > b ?
    max(a, ::std::forward<A>(args)...) :
    max(b, ::std::forward<A>(args)...);
}

template <typename T, typename ...A>
constexpr inline ::std::enable_if_t<
  bool(sizeof...(A)) &&
  all_of<
    ::std::is_same<
      typename ::std::decay<T>::type,
      typename ::std::decay<A>::type
    >...
  >{},
  T
>
min(T const& a, T const& b, A&& ...args) noexcept
{
  return a < b ?
    min(a, ::std::forward<A>(args)...) :
    min(b, ::std::forward<A>(args)...);
}

template <typename ...A>
constexpr inline typename ::std::enable_if_t<
  bool(sizeof...(A)) &&
  all_of<
    ::std::is_same<
      typename ::std::decay<typename front<A...>::type>::type,
      typename ::std::decay<A>::type
    >...
  >{},
  ::std::pair<
    typename ::std::decay<typename front<A...>::type>::type,
    typename ::std::decay<typename front<A...>::type>::type
  >
>
minmax(A&& ...args) noexcept
{
  return {
    min(::std::forward<A>(args)...),
    max(::std::forward<A>(args)...)
  };
}

template<typename T, typename U, typename V>
constexpr inline ::std::enable_if_t<
  ::std::is_same<T, U>{} &&
  ::std::is_same<U, V>{},
  T const&
>
clamp(T const& v, U const& lo, V const& hi) noexcept
{
  return v < lo ?
    lo :
    hi < v ?
      hi :
      v;
}

}

#endif // GENERIC_ALGORITHM_HPP
<commit_msg>some fixes<commit_after>#ifndef GENERIC_ALGORITHM_HPP
# define GENERIC_ALGORITHM_HPP
# pragma once

#include <cstddef>

#include <type_traits>

#include <utility>

#include "meta.hpp"

namespace generic
{

// min, max
template <typename T>
constexpr inline T const& max(T const& a, T const& b) noexcept
{
  return b < a ? a : b;
}

template <typename T>
constexpr inline T const& min(T const& a, T const& b) noexcept
{
  return a < b ? a : b;
}

template <typename T, typename ...A>
constexpr inline ::std::enable_if_t<
  bool(sizeof...(A)) &&
  all_of<
    ::std::is_same<
      typename ::std::decay<T>::type,
      typename ::std::decay<A>::type
    >...
  >{},
  T
>
max(T const& a, T const& b, A&& ...args) noexcept
{
  return b < a ?
    max(a, ::std::forward<A>(args)...) :
    max(b, ::std::forward<A>(args)...);
}

template <typename T, typename ...A>
constexpr inline ::std::enable_if_t<
  bool(sizeof...(A)) &&
  all_of<
    ::std::is_same<
      typename ::std::decay<T>::type,
      typename ::std::decay<A>::type
    >...
  >{},
  T
>
min(T const& a, T const& b, A&& ...args) noexcept
{
  return a < b ?
    min(a, ::std::forward<A>(args)...) :
    min(b, ::std::forward<A>(args)...);
}

template <typename ...A>
constexpr inline typename ::std::enable_if_t<
  bool(sizeof...(A)) &&
  all_of<
    ::std::is_same<
      typename ::std::decay<typename front<A...>::type>::type,
      typename ::std::decay<A>::type
    >...
  >{},
  ::std::pair<
    typename ::std::decay<typename front<A...>::type>::type,
    typename ::std::decay<typename front<A...>::type>::type
  >
>
minmax(A&& ...args) noexcept
{
  return {
    min(::std::forward<A>(args)...),
    max(::std::forward<A>(args)...)
  };
}

template<typename T, typename U, typename V>
constexpr inline ::std::enable_if_t<
  ::std::is_same<T, U>{} &&
  ::std::is_same<U, V>{},
  T const&
>
clamp(T const& v, U const& lo, V const& hi) noexcept
{
  return v < lo ?
    lo :
    hi < v ?
      hi :
      v;
}

}

#endif // GENERIC_ALGORITHM_HPP
<|endoftext|>