<commit_before>/*************************************************************************/
/*  file_access_pack.cpp                                                 */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md)    */
/*                                                                       */
/* 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 "file_access_pack.h"

#include "core/version.h"

#include <stdio.h>

#define PACK_VERSION 1

Error PackedData::add_pack(const String &p_path) {

	for (int i = 0; i < sources.size(); i++) {

		if (sources[i]->try_open_pack(p_path)) {

			return OK;
		};
	};

	return ERR_FILE_UNRECOGNIZED;
};

void PackedData::add_path(const String &pkg_path, const String &path, uint64_t ofs, uint64_t size, const uint8_t *p_md5, PackSource *p_src) {

	PathMD5 pmd5(path.md5_buffer());
	//printf("adding path %ls, %lli, %lli\n", path.c_str(), pmd5.a, pmd5.b);

	bool exists = files.has(pmd5);

	PackedFile pf;
	pf.pack = pkg_path;
	pf.offset = ofs;
	pf.size = size;
	for (int i = 0; i < 16; i++)
		pf.md5[i] = p_md5[i];
	pf.src = p_src;

	files[pmd5] = pf;

	if (!exists) {
		//search for dir
		String p = path.replace_first("res://", "");
		PackedDir *cd = root;

		if (p.find("/") != -1) { //in a subdir

			Vector<String> ds = p.get_base_dir().split("/");

			for (int j = 0; j < ds.size(); j++) {

				if (!cd->subdirs.has(ds[j])) {

					PackedDir *pd = memnew(PackedDir);
					pd->name = ds[j];
					pd->parent = cd;
					cd->subdirs[pd->name] = pd;
					cd = pd;
				} else {
					cd = cd->subdirs[ds[j]];
				}
			}
		}
		String filename = path.get_file();
		// Don't add as a file if the path points to a directoryy
		if (!filename.empty()) {
			cd->files.insert(filename);
		}
	}
}

void PackedData::add_pack_source(PackSource *p_source) {

	if (p_source != NULL) {
		sources.push_back(p_source);
	}
};

PackedData *PackedData::singleton = NULL;

PackedData::PackedData() {

	singleton = this;
	root = memnew(PackedDir);
	root->parent = NULL;
	disabled = false;

	add_pack_source(memnew(PackedSourcePCK));
}

void PackedData::_free_packed_dirs(PackedDir *p_dir) {

	for (Map<String, PackedDir *>::Element *E = p_dir->subdirs.front(); E; E = E->next())
		_free_packed_dirs(E->get());
	memdelete(p_dir);
}

PackedData::~PackedData() {

	for (int i = 0; i < sources.size(); i++) {
		memdelete(sources[i]);
	}
	_free_packed_dirs(root);
}

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

bool PackedSourcePCK::try_open_pack(const String &p_path) {

	FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
	if (!f)
		return false;

	//printf("try open %ls!\n", p_path.c_str());

	uint32_t magic = f->get_32();

	if (magic != 0x43504447) {
		//maybe at the end.... self contained exe
		f->seek_end();
		f->seek(f->get_position() - 4);
		magic = f->get_32();
		if (magic != 0x43504447) {

			memdelete(f);
			return false;
		}
		f->seek(f->get_position() - 12);

		uint64_t ds = f->get_64();
		f->seek(f->get_position() - ds - 8);

		magic = f->get_32();
		if (magic != 0x43504447) {

			memdelete(f);
			return false;
		}
	}

	uint32_t version = f->get_32();
	uint32_t ver_major = f->get_32();
	uint32_t ver_minor = f->get_32();
	f->get_32(); // ver_rev

	ERR_FAIL_COND_V_MSG(version != PACK_VERSION, false, "Pack version unsupported: " + itos(version) + ".");
	ERR_FAIL_COND_V_MSG(ver_major > VERSION_MAJOR || (ver_major == VERSION_MAJOR && ver_minor > VERSION_MINOR), false, "Pack created with a newer version of the engine: " + itos(ver_major) + "." + itos(ver_minor) + ".");

	for (int i = 0; i < 16; i++) {
		//reserved
		f->get_32();
	}

	int file_count = f->get_32();

	for (int i = 0; i < file_count; i++) {

		uint32_t sl = f->get_32();
		CharString cs;
		cs.resize(sl + 1);
		f->get_buffer((uint8_t *)cs.ptr(), sl);
		cs[sl] = 0;

		String path;
		path.parse_utf8(cs.ptr());

		uint64_t ofs = f->get_64();
		uint64_t size = f->get_64();
		uint8_t md5[16];
		f->get_buffer(md5, 16);
		PackedData::get_singleton()->add_path(p_path, path, ofs, size, md5, this);
	};

	return true;
};

FileAccess *PackedSourcePCK::get_file(const String &p_path, PackedData::PackedFile *p_file) {

	return memnew(FileAccessPack(p_path, *p_file));
};

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

Error FileAccessPack::_open(const String &p_path, int p_mode_flags) {

	ERR_FAIL_V(ERR_UNAVAILABLE);
	return ERR_UNAVAILABLE;
}

void FileAccessPack::close() {

	f->close();
}

bool FileAccessPack::is_open() const {

	return f->is_open();
}

void FileAccessPack::seek(size_t p_position) {

	if (p_position > pf.size) {
		eof = true;
	} else {
		eof = false;
	}

	f->seek(pf.offset + p_position);
	pos = p_position;
}
void FileAccessPack::seek_end(int64_t p_position) {

	seek(pf.size + p_position);
}
size_t FileAccessPack::get_position() const {

	return pos;
}
size_t FileAccessPack::get_len() const {

	return pf.size;
}

bool FileAccessPack::eof_reached() const {

	return eof;
}

uint8_t FileAccessPack::get_8() const {

	if (pos >= pf.size) {
		eof = true;
		return 0;
	}

	pos++;
	return f->get_8();
}

int FileAccessPack::get_buffer(uint8_t *p_dst, int p_length) const {

	if (eof)
		return 0;

	uint64_t to_read = p_length;
	if (to_read + pos > pf.size) {
		eof = true;
		to_read = int64_t(pf.size) - int64_t(pos);
	}

	pos += p_length;

	if (to_read <= 0)
		return 0;
	f->get_buffer(p_dst, to_read);

	return to_read;
}

void FileAccessPack::set_endian_swap(bool p_swap) {
	FileAccess::set_endian_swap(p_swap);
	f->set_endian_swap(p_swap);
}

Error FileAccessPack::get_error() const {

	if (eof)
		return ERR_FILE_EOF;
	return OK;
}

void FileAccessPack::flush() {

	ERR_FAIL();
}

void FileAccessPack::store_8(uint8_t p_dest) {

	ERR_FAIL();
}

void FileAccessPack::store_buffer(const uint8_t *p_src, int p_length) {

	ERR_FAIL();
}

bool FileAccessPack::file_exists(const String &p_name) {

	return false;
}

FileAccessPack::FileAccessPack(const String &p_path, const PackedData::PackedFile &p_file) :
		pf(p_file),
		f(FileAccess::open(pf.pack, FileAccess::READ)) {

	ERR_FAIL_COND_MSG(!f, "Can't open pack-referenced file: " + String(pf.pack) + ".");

	f->seek(pf.offset);
	pos = 0;
	eof = false;
}

FileAccessPack::~FileAccessPack() {
	if (f)
		memdelete(f);
}

//////////////////////////////////////////////////////////////////////////////////
// DIR ACCESS
//////////////////////////////////////////////////////////////////////////////////

Error DirAccessPack::list_dir_begin() {

	list_dirs.clear();
	list_files.clear();

	for (Map<String, PackedData::PackedDir *>::Element *E = current->subdirs.front(); E; E = E->next()) {

		list_dirs.push_back(E->key());
	}

	for (Set<String>::Element *E = current->files.front(); E; E = E->next()) {

		list_files.push_back(E->get());
	}

	return OK;
}

String DirAccessPack::get_next() {

	if (list_dirs.size()) {
		cdir = true;
		String d = list_dirs.front()->get();
		list_dirs.pop_front();
		return d;
	} else if (list_files.size()) {
		cdir = false;
		String f = list_files.front()->get();
		list_files.pop_front();
		return f;
	} else {
		return String();
	}
}
bool DirAccessPack::current_is_dir() const {

	return cdir;
}
bool DirAccessPack::current_is_hidden() const {

	return false;
}
void DirAccessPack::list_dir_end() {

	list_dirs.clear();
	list_files.clear();
}

int DirAccessPack::get_drive_count() {

	return 0;
}
String DirAccessPack::get_drive(int p_drive) {

	return "";
}

Error DirAccessPack::change_dir(String p_dir) {

	String nd = p_dir.replace("\\", "/");
	bool absolute = false;
	if (nd.begins_with("res://")) {
		nd = nd.replace_first("res://", "");
		absolute = true;
	}

	nd = nd.simplify_path();

	if (nd == "") nd = ".";

	if (nd.begins_with("/")) {
		nd = nd.replace_first("/", "");
		absolute = true;
	}

	Vector<String> paths = nd.split("/");

	PackedData::PackedDir *pd;

	if (absolute)
		pd = PackedData::get_singleton()->root;
	else
		pd = current;

	for (int i = 0; i < paths.size(); i++) {

		String p = paths[i];
		if (p == ".") {
			continue;
		} else if (p == "..") {
			if (pd->parent) {
				pd = pd->parent;
			}
		} else if (pd->subdirs.has(p)) {

			pd = pd->subdirs[p];

		} else {

			return ERR_INVALID_PARAMETER;
		}
	}

	current = pd;

	return OK;
}

String DirAccessPack::get_current_dir() {

	PackedData::PackedDir *pd = current;
	String p = current->name;

	while (pd->parent) {
		pd = pd->parent;
		p = pd->name.plus_file(p);
	}

	return "res://" + p;
}

bool DirAccessPack::file_exists(String p_file) {

	return current->files.has(p_file);
}

bool DirAccessPack::dir_exists(String p_dir) {

	return current->subdirs.has(p_dir);
}

Error DirAccessPack::make_dir(String p_dir) {

	return ERR_UNAVAILABLE;
}

Error DirAccessPack::rename(String p_from, String p_to) {

	return ERR_UNAVAILABLE;
}
Error DirAccessPack::remove(String p_name) {

	return ERR_UNAVAILABLE;
}

size_t DirAccessPack::get_space_left() {

	return 0;
}

String DirAccessPack::get_filesystem_type() const {
	return "PCK";
}

DirAccessPack::DirAccessPack() {

	current = PackedData::get_singleton()->root;
	cdir = false;
}

DirAccessPack::~DirAccessPack() {
}
<commit_msg>DirAccessPack: Fix dir_exists and file_exists for res:// paths<commit_after>/*************************************************************************/
/*  file_access_pack.cpp                                                 */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md)    */
/*                                                                       */
/* 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 "file_access_pack.h"

#include "core/version.h"

#include <stdio.h>

#define PACK_VERSION 1

Error PackedData::add_pack(const String &p_path) {

	for (int i = 0; i < sources.size(); i++) {

		if (sources[i]->try_open_pack(p_path)) {

			return OK;
		};
	};

	return ERR_FILE_UNRECOGNIZED;
};

void PackedData::add_path(const String &pkg_path, const String &path, uint64_t ofs, uint64_t size, const uint8_t *p_md5, PackSource *p_src) {

	PathMD5 pmd5(path.md5_buffer());
	//printf("adding path %ls, %lli, %lli\n", path.c_str(), pmd5.a, pmd5.b);

	bool exists = files.has(pmd5);

	PackedFile pf;
	pf.pack = pkg_path;
	pf.offset = ofs;
	pf.size = size;
	for (int i = 0; i < 16; i++)
		pf.md5[i] = p_md5[i];
	pf.src = p_src;

	files[pmd5] = pf;

	if (!exists) {
		//search for dir
		String p = path.replace_first("res://", "");
		PackedDir *cd = root;

		if (p.find("/") != -1) { //in a subdir

			Vector<String> ds = p.get_base_dir().split("/");

			for (int j = 0; j < ds.size(); j++) {

				if (!cd->subdirs.has(ds[j])) {

					PackedDir *pd = memnew(PackedDir);
					pd->name = ds[j];
					pd->parent = cd;
					cd->subdirs[pd->name] = pd;
					cd = pd;
				} else {
					cd = cd->subdirs[ds[j]];
				}
			}
		}
		String filename = path.get_file();
		// Don't add as a file if the path points to a directory
		if (!filename.empty()) {
			cd->files.insert(filename);
		}
	}
}

void PackedData::add_pack_source(PackSource *p_source) {

	if (p_source != NULL) {
		sources.push_back(p_source);
	}
};

PackedData *PackedData::singleton = NULL;

PackedData::PackedData() {

	singleton = this;
	root = memnew(PackedDir);
	root->parent = NULL;
	disabled = false;

	add_pack_source(memnew(PackedSourcePCK));
}

void PackedData::_free_packed_dirs(PackedDir *p_dir) {

	for (Map<String, PackedDir *>::Element *E = p_dir->subdirs.front(); E; E = E->next())
		_free_packed_dirs(E->get());
	memdelete(p_dir);
}

PackedData::~PackedData() {

	for (int i = 0; i < sources.size(); i++) {
		memdelete(sources[i]);
	}
	_free_packed_dirs(root);
}

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

bool PackedSourcePCK::try_open_pack(const String &p_path) {

	FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
	if (!f)
		return false;

	//printf("try open %ls!\n", p_path.c_str());

	uint32_t magic = f->get_32();

	if (magic != 0x43504447) {
		//maybe at the end.... self contained exe
		f->seek_end();
		f->seek(f->get_position() - 4);
		magic = f->get_32();
		if (magic != 0x43504447) {

			memdelete(f);
			return false;
		}
		f->seek(f->get_position() - 12);

		uint64_t ds = f->get_64();
		f->seek(f->get_position() - ds - 8);

		magic = f->get_32();
		if (magic != 0x43504447) {

			memdelete(f);
			return false;
		}
	}

	uint32_t version = f->get_32();
	uint32_t ver_major = f->get_32();
	uint32_t ver_minor = f->get_32();
	f->get_32(); // ver_rev

	ERR_FAIL_COND_V_MSG(version != PACK_VERSION, false, "Pack version unsupported: " + itos(version) + ".");
	ERR_FAIL_COND_V_MSG(ver_major > VERSION_MAJOR || (ver_major == VERSION_MAJOR && ver_minor > VERSION_MINOR), false, "Pack created with a newer version of the engine: " + itos(ver_major) + "." + itos(ver_minor) + ".");

	for (int i = 0; i < 16; i++) {
		//reserved
		f->get_32();
	}

	int file_count = f->get_32();

	for (int i = 0; i < file_count; i++) {

		uint32_t sl = f->get_32();
		CharString cs;
		cs.resize(sl + 1);
		f->get_buffer((uint8_t *)cs.ptr(), sl);
		cs[sl] = 0;

		String path;
		path.parse_utf8(cs.ptr());

		uint64_t ofs = f->get_64();
		uint64_t size = f->get_64();
		uint8_t md5[16];
		f->get_buffer(md5, 16);
		PackedData::get_singleton()->add_path(p_path, path, ofs, size, md5, this);
	};

	return true;
};

FileAccess *PackedSourcePCK::get_file(const String &p_path, PackedData::PackedFile *p_file) {

	return memnew(FileAccessPack(p_path, *p_file));
};

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

Error FileAccessPack::_open(const String &p_path, int p_mode_flags) {

	ERR_FAIL_V(ERR_UNAVAILABLE);
	return ERR_UNAVAILABLE;
}

void FileAccessPack::close() {

	f->close();
}

bool FileAccessPack::is_open() const {

	return f->is_open();
}

void FileAccessPack::seek(size_t p_position) {

	if (p_position > pf.size) {
		eof = true;
	} else {
		eof = false;
	}

	f->seek(pf.offset + p_position);
	pos = p_position;
}
void FileAccessPack::seek_end(int64_t p_position) {

	seek(pf.size + p_position);
}
size_t FileAccessPack::get_position() const {

	return pos;
}
size_t FileAccessPack::get_len() const {

	return pf.size;
}

bool FileAccessPack::eof_reached() const {

	return eof;
}

uint8_t FileAccessPack::get_8() const {

	if (pos >= pf.size) {
		eof = true;
		return 0;
	}

	pos++;
	return f->get_8();
}

int FileAccessPack::get_buffer(uint8_t *p_dst, int p_length) const {

	if (eof)
		return 0;

	uint64_t to_read = p_length;
	if (to_read + pos > pf.size) {
		eof = true;
		to_read = int64_t(pf.size) - int64_t(pos);
	}

	pos += p_length;

	if (to_read <= 0)
		return 0;
	f->get_buffer(p_dst, to_read);

	return to_read;
}

void FileAccessPack::set_endian_swap(bool p_swap) {
	FileAccess::set_endian_swap(p_swap);
	f->set_endian_swap(p_swap);
}

Error FileAccessPack::get_error() const {

	if (eof)
		return ERR_FILE_EOF;
	return OK;
}

void FileAccessPack::flush() {

	ERR_FAIL();
}

void FileAccessPack::store_8(uint8_t p_dest) {

	ERR_FAIL();
}

void FileAccessPack::store_buffer(const uint8_t *p_src, int p_length) {

	ERR_FAIL();
}

bool FileAccessPack::file_exists(const String &p_name) {

	return false;
}

FileAccessPack::FileAccessPack(const String &p_path, const PackedData::PackedFile &p_file) :
		pf(p_file),
		f(FileAccess::open(pf.pack, FileAccess::READ)) {

	ERR_FAIL_COND_MSG(!f, "Can't open pack-referenced file: " + String(pf.pack) + ".");

	f->seek(pf.offset);
	pos = 0;
	eof = false;
}

FileAccessPack::~FileAccessPack() {
	if (f)
		memdelete(f);
}

//////////////////////////////////////////////////////////////////////////////////
// DIR ACCESS
//////////////////////////////////////////////////////////////////////////////////

Error DirAccessPack::list_dir_begin() {

	list_dirs.clear();
	list_files.clear();

	for (Map<String, PackedData::PackedDir *>::Element *E = current->subdirs.front(); E; E = E->next()) {

		list_dirs.push_back(E->key());
	}

	for (Set<String>::Element *E = current->files.front(); E; E = E->next()) {

		list_files.push_back(E->get());
	}

	return OK;
}

String DirAccessPack::get_next() {

	if (list_dirs.size()) {
		cdir = true;
		String d = list_dirs.front()->get();
		list_dirs.pop_front();
		return d;
	} else if (list_files.size()) {
		cdir = false;
		String f = list_files.front()->get();
		list_files.pop_front();
		return f;
	} else {
		return String();
	}
}
bool DirAccessPack::current_is_dir() const {

	return cdir;
}
bool DirAccessPack::current_is_hidden() const {

	return false;
}
void DirAccessPack::list_dir_end() {

	list_dirs.clear();
	list_files.clear();
}

int DirAccessPack::get_drive_count() {

	return 0;
}
String DirAccessPack::get_drive(int p_drive) {

	return "";
}

Error DirAccessPack::change_dir(String p_dir) {

	String nd = p_dir.replace("\\", "/");
	bool absolute = false;
	if (nd.begins_with("res://")) {
		nd = nd.replace_first("res://", "");
		absolute = true;
	}

	nd = nd.simplify_path();

	if (nd == "") nd = ".";

	if (nd.begins_with("/")) {
		nd = nd.replace_first("/", "");
		absolute = true;
	}

	Vector<String> paths = nd.split("/");

	PackedData::PackedDir *pd;

	if (absolute)
		pd = PackedData::get_singleton()->root;
	else
		pd = current;

	for (int i = 0; i < paths.size(); i++) {

		String p = paths[i];
		if (p == ".") {
			continue;
		} else if (p == "..") {
			if (pd->parent) {
				pd = pd->parent;
			}
		} else if (pd->subdirs.has(p)) {

			pd = pd->subdirs[p];

		} else {

			return ERR_INVALID_PARAMETER;
		}
	}

	current = pd;

	return OK;
}

String DirAccessPack::get_current_dir() {

	PackedData::PackedDir *pd = current;
	String p = current->name;

	while (pd->parent) {
		pd = pd->parent;
		p = pd->name.plus_file(p);
	}

	return "res://" + p;
}

bool DirAccessPack::file_exists(String p_file) {

	p_file = fix_path(p_file);

	return current->files.has(p_file);
}

bool DirAccessPack::dir_exists(String p_dir) {

	p_dir = fix_path(p_dir);

	return current->subdirs.has(p_dir);
}

Error DirAccessPack::make_dir(String p_dir) {

	return ERR_UNAVAILABLE;
}

Error DirAccessPack::rename(String p_from, String p_to) {

	return ERR_UNAVAILABLE;
}
Error DirAccessPack::remove(String p_name) {

	return ERR_UNAVAILABLE;
}

size_t DirAccessPack::get_space_left() {

	return 0;
}

String DirAccessPack::get_filesystem_type() const {
	return "PCK";
}

DirAccessPack::DirAccessPack() {

	current = PackedData::get_singleton()->root;
	cdir = false;
}

DirAccessPack::~DirAccessPack() {
}
<|endoftext|>


<commit_before>/**
 * @file ada_delta.hpp
 * @author Marcus Edel
 *
 * Implmentation of the RmsProp optimizer. Adadelta is an optimizer that uses
 * the magnitude of recent gradients and steps to obtain an adaptive step rate.
 */
#ifndef __MLPACK_METHODS_ANN_OPTIMIZER_ADA_DELTA_HPP
#define __MLPACK_METHODS_ANN_OPTIMIZER_ADA_DELTA_HPP

#include <mlpack/core.hpp>

namespace mlpack {
namespace ann /** Artificial Neural Network. */ {

/**
 * Adadelta is an optimizer that uses the magnitude of recent gradients and
 * steps to obtain an adaptive step rate. In its basic form, given a step rate
 * \f$ \gamma \f$ and a decay term \f$ \alpha \f$ we perform the following
 * updates:
 *
 * \f[
 *  g_t &=& (1 - \gamma)f'(\Delta_t)^2 + \gammag_{t - 1} \\
 *  \vec{\Delta} \Delta_t = \alpha \frac{\sqrt(s_{t-1} +
 *  \epsilon)}{\sqrt{g_t + \epsilon}} f'(\Delta_t) \\
 *  \Delta_{t + 1} &=& \Delta_t - \vec{\Delta} \Delta_t \\
 *  s_t &=& (1 - \gamma) \vec{\Delta} \Delta_t^2 + \gammas_{t - 1}
 * \f]
 *
 * For more information, see the following.
 *
 * @code
 * @article{Zeiler2012,
 *   author    = {Matthew D. Zeiler},
 *   title     = {{ADADELTA:} An Adaptive Learning Rate Method},
 *   journal   = {CoRR},
 *   year      = {2012}
 * }
 * @endcode
 */
template<typename DecomposableFunctionType, typename DataType>
class AdaDelta
{
 public:
  /**
   * Construct the AdaDelta optimizer with the given function and parameters.
   *
   * @param function Function to be optimized (minimized).
   * @param rho Constant similar to that used in AdaDelta and Momentum methods.
   * @param eps The eps coefficient to avoid division by zero.
   */
  AdaDelta(DecomposableFunctionType& function,
          const double rho = 0.95,
          const double eps = 1e-6) :
      function(function),
      rho(rho),
      eps(eps)
  {
    // Nothing to do here.
  }

  /**
   * Optimize the given function using RmsProp.
   */
  void Optimize()
  {
    if (meanSquaredGradient.n_elem == 0)
    {
      meanSquaredGradient = function.Weights();
      meanSquaredGradient.zeros();

      meanSquaredGradientDx = meanSquaredGradient;
    }

    Optimize(function.Weights(), gradient, meanSquaredGradient,
        meanSquaredGradientDx);
  }

  /*
   * Sum up all gradients and store the results in the gradients storage.
   */
  void Update()
  {
    if (gradient.n_elem != 0)
    {
      DataType outputGradient;
      function.Gradient(outputGradient);
      gradient += outputGradient;
    }
    else
    {
      function.Gradient(gradient);
    }
  }

  /*
   * Reset the gradient storage.
   */
  void Reset()
  {
    gradient.zeros();
  }

 private:
  /**
   * Optimize the given function using AdaDelta.
   *
   * @param weights The weights that should be updated.
   * @param gradient The gradient used to update the weights.
   * @param meanSquaredGradient The current mean squared gradient Dx
   * @param meanSquaredGradientDx The current mean squared gradient.
   */
  template<typename eT>
  void Optimize(arma::Cube<eT>& weights,
                arma::Cube<eT>& gradient,
                arma::Cube<eT>& meanSquaredGradient,
                arma::Cube<eT>& meanSquaredGradientDx)
  {
    for (size_t s = 0; s < weights.n_slices; s++)
    {
      Optimize(weights.slice(s), gradient.slice(s), meanSquaredGradient.slice(s),
          meanSquaredGradientDx.slice(s));
    }
  }

  /**
   * Optimize the given function using AdaDelta.
   *
   * @param weights The weights that should be updated.
   * @param gradient The gradient used to update the weights.
   * @param meanSquaredGradient The current mean squared gradient Dx
   * @param meanSquaredGradientDx The current mean squared gradient.
   */
  template<typename eT>
  void Optimize(arma::Mat<eT>& weights,
                arma::Mat<eT>& gradient,
                arma::Mat<eT>& meanSquaredGradient,
                arma::Mat<eT>& meanSquaredGradientDx)
  {
    // Accumulate gradient.
    meanSquaredGradient *= rho;
    meanSquaredGradient += (1 - rho) * (gradient % gradient);
    arma::Mat<eT> dx = arma::sqrt((meanSquaredGradientDx + eps) /
        (meanSquaredGradient + eps)) % gradient;

    // Accumulate updates.
    meanSquaredGradientDx *= rho;
    meanSquaredGradientDx += (1 - rho) * (dx % dx);

    // Apply update.
    weights -= dx;
  }

  //! The instantiated function.
  DecomposableFunctionType& function;

  //! The value used as learning rate.
  const double rho;

  //! The value used as eps.
  const double eps;

  //! The current gradient.
  DataType gradient;

  //! The current mean squared gradient.
  DataType meanSquaredGradient;

  //! The current mean squared gradient Dx
  DataType meanSquaredGradientDx;
}; // class AdaDelta

}; // namespace ann
}; // namespace mlpack

#endif
<commit_msg>Add function to get the current gradient.<commit_after>/**
 * @file ada_delta.hpp
 * @author Marcus Edel
 *
 * Implmentation of the RmsProp optimizer. Adadelta is an optimizer that uses
 * the magnitude of recent gradients and steps to obtain an adaptive step rate.
 */
#ifndef __MLPACK_METHODS_ANN_OPTIMIZER_ADA_DELTA_HPP
#define __MLPACK_METHODS_ANN_OPTIMIZER_ADA_DELTA_HPP

#include <mlpack/core.hpp>

namespace mlpack {
namespace ann /** Artificial Neural Network. */ {

/**
 * Adadelta is an optimizer that uses the magnitude of recent gradients and
 * steps to obtain an adaptive step rate. In its basic form, given a step rate
 * \f$ \gamma \f$ and a decay term \f$ \alpha \f$ we perform the following
 * updates:
 *
 * \f[
 *  g_t &=& (1 - \gamma)f'(\Delta_t)^2 + \gammag_{t - 1} \\
 *  \vec{\Delta} \Delta_t = \alpha \frac{\sqrt(s_{t-1} +
 *  \epsilon)}{\sqrt{g_t + \epsilon}} f'(\Delta_t) \\
 *  \Delta_{t + 1} &=& \Delta_t - \vec{\Delta} \Delta_t \\
 *  s_t &=& (1 - \gamma) \vec{\Delta} \Delta_t^2 + \gammas_{t - 1}
 * \f]
 *
 * For more information, see the following.
 *
 * @code
 * @article{Zeiler2012,
 *   author    = {Matthew D. Zeiler},
 *   title     = {{ADADELTA:} An Adaptive Learning Rate Method},
 *   journal   = {CoRR},
 *   year      = {2012}
 * }
 * @endcode
 */
template<typename DecomposableFunctionType, typename DataType>
class AdaDelta
{
 public:
  /**
   * Construct the AdaDelta optimizer with the given function and parameters.
   *
   * @param function Function to be optimized (minimized).
   * @param rho Constant similar to that used in AdaDelta and Momentum methods.
   * @param eps The eps coefficient to avoid division by zero.
   */
  AdaDelta(DecomposableFunctionType& function,
          const double rho = 0.95,
          const double eps = 1e-6) :
      function(function),
      rho(rho),
      eps(eps),
      iteration(0)
  {
    // Nothing to do here.
  }

  /**
   * Optimize the given function using RmsProp.
   */
  void Optimize()
  {
    if (meanSquaredGradient.n_elem == 0)
    {
      meanSquaredGradient = function.Weights();
      meanSquaredGradient.zeros();

      meanSquaredGradientDx = meanSquaredGradient;
    }

    if (iteration > 1)
      gradient /= iteration;

    Optimize(function.Weights(), gradient, meanSquaredGradient,
        meanSquaredGradientDx);
  }

  /*
   * Sum up all gradients and store the results in the gradients storage.
   */
  void Update()
  {
    iteration++;

    if (gradient.n_elem != 0)
    {
      DataType outputGradient;
      function.Gradient(outputGradient);
      gradient += outputGradient;
    }
    else
    {
      function.Gradient(gradient);
    }
  }

  /*
   * Reset the gradient storage.
   */
  void Reset()
  {
    iteration = 0;
    gradient.zeros();
  }

  //! Get the gradient.
  DataType& Gradient() const { return gradient; }
  //! Modify the gradient.
  DataType& Gradient() { return gradient; }

 private:
  /**
   * Optimize the given function using AdaDelta.
   *
   * @param weights The weights that should be updated.
   * @param gradient The gradient used to update the weights.
   * @param meanSquaredGradient The current mean squared gradient Dx
   * @param meanSquaredGradientDx The current mean squared gradient.
   */
  template<typename eT>
  void Optimize(arma::Cube<eT>& weights,
                arma::Cube<eT>& gradient,
                arma::Cube<eT>& meanSquaredGradient,
                arma::Cube<eT>& meanSquaredGradientDx)
  {
    for (size_t s = 0; s < weights.n_slices; s++)
    {
      Optimize(weights.slice(s), gradient.slice(s), meanSquaredGradient.slice(s),
          meanSquaredGradientDx.slice(s));
    }
  }

  /**
   * Optimize the given function using AdaDelta.
   *
   * @param weights The weights that should be updated.
   * @param gradient The gradient used to update the weights.
   * @param meanSquaredGradient The current mean squared gradient Dx
   * @param meanSquaredGradientDx The current mean squared gradient.
   */
  template<typename eT>
  void Optimize(arma::Mat<eT>& weights,
                arma::Mat<eT>& gradient,
                arma::Mat<eT>& meanSquaredGradient,
                arma::Mat<eT>& meanSquaredGradientDx)
  {
    // Accumulate gradient.
    meanSquaredGradient *= rho;
    meanSquaredGradient += (1 - rho) * (gradient % gradient);
    arma::Mat<eT> dx = arma::sqrt((meanSquaredGradientDx + eps) /
        (meanSquaredGradient + eps)) % gradient;

    // Accumulate updates.
    meanSquaredGradientDx *= rho;
    meanSquaredGradientDx += (1 - rho) * (dx % dx);

    // Apply update.
    weights -= dx;
  }

  //! The instantiated function.
  DecomposableFunctionType& function;

  //! The value used as learning rate.
  const double rho;

  //! The value used as eps.
  const double eps;

  //! The current gradient.
  DataType gradient;

  //! The current mean squared gradient.
  DataType meanSquaredGradient;

  //! The current mean squared gradient Dx
  DataType meanSquaredGradientDx;

  //! The locally stored number of iterations.
  size_t iteration;
}; // class AdaDelta

}; // namespace ann
}; // namespace mlpack

#endif
<|endoftext|>


<commit_before>#include "Keyboard.h"

#include "imgui/imgui.h"

#include <algorithm>
#include <iostream>
namespace Preferences {

Keyboard::Keyboard(KeyBindings &keybindings, Confparse &obvconfig) : keybindings(keybindings), obvconfig(obvconfig) {
}

void Keyboard::menuItem() {
	if (ImGui::MenuItem("Keyboard Preferences")) {
		shown = true;
	}
}

void Keyboard::render() {
	bool close_button_not_clicked = true;
	auto &io = ImGui::GetIO();
	ImGui::SetNextWindowPos(ImVec2(io.DisplaySize.x * 0.5f, io.DisplaySize.y * 0.5f), 0, ImVec2(0.5f, 0.5f));
	if (ImGui::BeginPopupModal("Keyboard Preferences", &close_button_not_clicked, ImGuiWindowFlags_AlwaysAutoResize)) {
		shown = false;

		// Find how many columns we need to show all the keybindings
		auto maxbindings = std::max_element(keybindings.keybindings.begin(), keybindings.keybindings.end(),
							[](const std::pair<std::string, std::vector<KeyBinding>> &a, const std::pair<std::string, std::vector<KeyBinding>> &b){ // C++14 has auto lambda argument deduction, would make it cleaner…
								return a.second.size() < b.second.size();});
		// total number of columns: name + keybindings + add button
		auto colcount = 1 + (maxbindings != keybindings.keybindings.end() ? maxbindings->second.size() : 0) + 1;

		if (ImGui::BeginTable("KeyBindings", colcount,
			ImGuiTableFlags_SizingPolicyFixedX // size according to content
			| ImGuiTableFlags_RowBg // alternating background colors
			| ImGuiTableFlags_BordersH
			| ImGuiTableFlags_BordersV)) {

			for (auto &kbs : keybindings.keybindings) {
				ImGui::TableNextRow();
				ImGui::TableSetColumnIndex(0);
				ImGui::Text("%s", kbs.first.c_str()); // binding name

				auto &bindings = kbs.second; // reference because we add/delete from it below

				// Show all bindings, potentially newly added button will be shown next frame since we need to compute number of column again first
				auto colindex = 1;
				for (auto it = bindings.begin(); it != bindings.end();) {
					auto keys = it->to_string();

					ImGui::TableSetColumnIndex(colindex);
					if (ImGui::SmallButton(("X##" + kbs.first + std::to_string(colindex)).c_str())) {
						// Erase binding when clicking on X button
						it = bindings.erase(it);
					} else {
						// warning: iterator incremented here since it must not be incremented after reaffectation if binding is erased
						++it;
					}
					ImGui::SameLine();
					ImGui::Text("%s", keys.c_str());

					colindex++;
				}

				// Add new binding after pressing add button, keep that after showing all bindings
				if (addingName == kbs.first) {
					// Check if a key is pressed
					for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) {
						if (io.KeysDown[i]) {
							auto scancode = static_cast<SDL_Scancode>(i);
							SDL_Keycode kc = SDL_GetKeyFromScancode(scancode);

							// Ignore modifier keys, cannot be a final key
							if (!keybindings.keyModifiers.isSDLKModifier(kc)) {
								addingScancode = scancode;
								addingBinding = KeyBinding(kc);
							}
						}
					}
					// Get the modifier keys pressed
					addingBinding.modifiers = keybindings.keyModifiers.pressed();

					// Add binding once non-modifier key is released
					if (addingScancode != SDL_SCANCODE_UNKNOWN && ImGui::IsKeyReleased(addingScancode)) {
						bindings.push_back(addingBinding);

						addingScancode = SDL_SCANCODE_UNKNOWN;
						addingName = {};
						addingBinding = {};
					}
				}

				ImGui::TableSetColumnIndex(colindex);
				if (addingName == kbs.first) {
					// Adding a new key binding
					auto keys = addingBinding.to_string();
					if (ImGui::SmallButton(("X##adding" + kbs.first).c_str())) {
						// Stop adding new keybinding
						addingScancode = SDL_SCANCODE_UNKNOWN;
						addingName = std::string{};
						addingBinding = KeyBinding{};
					}
					ImGui::SameLine();
					if (!keys.empty()) {
						// Show current pressed keys
						ImGui::Text("%s", keys.c_str());
					} else {
						// Or a message indicating to press a key
						ImGui::Text("%s", "<Press a key>");
					}
				} else {
					// Show add button
					if (ImGui::SmallButton(("Add##" + kbs.first).c_str())) {
						addingName = kbs.first;
					}
				}
			}

			ImGui::EndTable();
		}

		ImGui::Text("Note: %c and %c cannot be used as key bindings.", keybindings.bindingSeparator, keybindings.modifierSeparator);

		if (ImGui::Button("Save")) {
			keybindings.writeToConfig(obvconfig);
			ImGui::CloseCurrentPopup();
		}
		ImGui::SameLine();
		if (ImGui::Button("Cancel") || keybindings.isPressed("CloseDialog") || !close_button_not_clicked) {
			keybindings.readFromConfig(obvconfig);
			ImGui::CloseCurrentPopup();
		}
		ImGui::SameLine();
		if (ImGui::Button("Default")) {
			keybindings.reset();
		}

		ImGui::EndPopup();
	}

	if (!close_button_not_clicked) { // modal title bar close button clicked
		printf("Close\n");
		keybindings.readFromConfig(obvconfig);
	}

	if (shown) {
		ImGui::OpenPopup("Keyboard Preferences");
	}
}

} // namespace Preferences
<commit_msg>Use auto lambda argument in GUI/Preferences/Keyboard.cpp since we have C++17<commit_after>#include "Keyboard.h"

#include "imgui/imgui.h"

#include <algorithm>
#include <iostream>
namespace Preferences {

Keyboard::Keyboard(KeyBindings &keybindings, Confparse &obvconfig) : keybindings(keybindings), obvconfig(obvconfig) {
}

void Keyboard::menuItem() {
	if (ImGui::MenuItem("Keyboard Preferences")) {
		shown = true;
	}
}

void Keyboard::render() {
	bool close_button_not_clicked = true;
	auto &io = ImGui::GetIO();
	ImGui::SetNextWindowPos(ImVec2(io.DisplaySize.x * 0.5f, io.DisplaySize.y * 0.5f), 0, ImVec2(0.5f, 0.5f));
	if (ImGui::BeginPopupModal("Keyboard Preferences", &close_button_not_clicked, ImGuiWindowFlags_AlwaysAutoResize)) {
		shown = false;

		// Find how many columns we need to show all the keybindings
		auto maxbindings = std::max_element(keybindings.keybindings.begin(), keybindings.keybindings.end(),
							[](auto a, auto b){ return a.second.size() < b.second.size(); });
		// total number of columns: name + keybindings + add button
		auto colcount = 1 + (maxbindings != keybindings.keybindings.end() ? maxbindings->second.size() : 0) + 1;

		if (ImGui::BeginTable("KeyBindings", colcount,
			ImGuiTableFlags_SizingPolicyFixedX // size according to content
			| ImGuiTableFlags_RowBg // alternating background colors
			| ImGuiTableFlags_BordersH
			| ImGuiTableFlags_BordersV)) {

			for (auto &kbs : keybindings.keybindings) {
				ImGui::TableNextRow();
				ImGui::TableSetColumnIndex(0);
				ImGui::Text("%s", kbs.first.c_str()); // binding name

				auto &bindings = kbs.second; // reference because we add/delete from it below

				// Show all bindings, potentially newly added button will be shown next frame since we need to compute number of column again first
				auto colindex = 1;
				for (auto it = bindings.begin(); it != bindings.end();) {
					auto keys = it->to_string();

					ImGui::TableSetColumnIndex(colindex);
					if (ImGui::SmallButton(("X##" + kbs.first + std::to_string(colindex)).c_str())) {
						// Erase binding when clicking on X button
						it = bindings.erase(it);
					} else {
						// warning: iterator incremented here since it must not be incremented after reaffectation if binding is erased
						++it;
					}
					ImGui::SameLine();
					ImGui::Text("%s", keys.c_str());

					colindex++;
				}

				// Add new binding after pressing add button, keep that after showing all bindings
				if (addingName == kbs.first) {
					// Check if a key is pressed
					for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) {
						if (io.KeysDown[i]) {
							auto scancode = static_cast<SDL_Scancode>(i);
							SDL_Keycode kc = SDL_GetKeyFromScancode(scancode);

							// Ignore modifier keys, cannot be a final key
							if (!keybindings.keyModifiers.isSDLKModifier(kc)) {
								addingScancode = scancode;
								addingBinding = KeyBinding(kc);
							}
						}
					}
					// Get the modifier keys pressed
					addingBinding.modifiers = keybindings.keyModifiers.pressed();

					// Add binding once non-modifier key is released
					if (addingScancode != SDL_SCANCODE_UNKNOWN && ImGui::IsKeyReleased(addingScancode)) {
						bindings.push_back(addingBinding);

						addingScancode = SDL_SCANCODE_UNKNOWN;
						addingName = {};
						addingBinding = {};
					}
				}

				ImGui::TableSetColumnIndex(colindex);
				if (addingName == kbs.first) {
					// Adding a new key binding
					auto keys = addingBinding.to_string();
					if (ImGui::SmallButton(("X##adding" + kbs.first).c_str())) {
						// Stop adding new keybinding
						addingScancode = SDL_SCANCODE_UNKNOWN;
						addingName = std::string{};
						addingBinding = KeyBinding{};
					}
					ImGui::SameLine();
					if (!keys.empty()) {
						// Show current pressed keys
						ImGui::Text("%s", keys.c_str());
					} else {
						// Or a message indicating to press a key
						ImGui::Text("%s", "<Press a key>");
					}
				} else {
					// Show add button
					if (ImGui::SmallButton(("Add##" + kbs.first).c_str())) {
						addingName = kbs.first;
					}
				}
			}

			ImGui::EndTable();
		}

		ImGui::Text("Note: %c and %c cannot be used as key bindings.", keybindings.bindingSeparator, keybindings.modifierSeparator);

		if (ImGui::Button("Save")) {
			keybindings.writeToConfig(obvconfig);
			ImGui::CloseCurrentPopup();
		}
		ImGui::SameLine();
		if (ImGui::Button("Cancel") || keybindings.isPressed("CloseDialog") || !close_button_not_clicked) {
			keybindings.readFromConfig(obvconfig);
			ImGui::CloseCurrentPopup();
		}
		ImGui::SameLine();
		if (ImGui::Button("Default")) {
			keybindings.reset();
		}

		ImGui::EndPopup();
	}

	if (!close_button_not_clicked) { // modal title bar close button clicked
		printf("Close\n");
		keybindings.readFromConfig(obvconfig);
	}

	if (shown) {
		ImGui::OpenPopup("Keyboard Preferences");
	}
}

} // namespace Preferences
<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2017.  All rights reserved
 */
//  TEST    Foundation::Containers::DataHyperRectangle
//      STATUS  PRELIMINARY
#include "Stroika/Foundation/StroikaPreComp.h"

#include <iostream>
#include <sstream>

#include "Stroika/Foundation/Containers/Concrete/DataHyperRectangle_DenseVector.h"
#include "Stroika/Foundation/Containers/Concrete/DataHyperRectangle_Sparse_stdmap.h"
#include "Stroika/Foundation/Containers/DataHyperRectangle.h"
#include "Stroika/Foundation/Debug/Assertions.h"
#include "Stroika/Foundation/Debug/Trace.h"

#include "../TestHarness/SimpleClass.h"
#include "../TestHarness/TestHarness.h"

using namespace Stroika;
using namespace Stroika::Foundation;
using namespace Stroika::Foundation::Containers;

namespace {
    void DoRegressionTests_ ()
    {
        {
            DataHyperRectangle2<int> x = Concrete::DataHyperRectangle_DenseVector<int, size_t, size_t>{3, 4};
            Verify (x.GetAt (2, 2) == 0);
        }
        {
            DataHyperRectangle2<int> x = Concrete::DataHyperRectangle_Sparse_stdmap<int, size_t, size_t>{};
            Verify (x.GetAt (2, 2) == 0);
        }
    }
}

int main (int argc, const char* argv[])
{
    Stroika::TestHarness::Setup ();
    return Stroika::TestHarness::PrintPassOrFail (DoRegressionTests_);
}
<commit_msg>tiny progress on regtest for datahypercube<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2017.  All rights reserved
 */
//  TEST    Foundation::Containers::DataHyperRectangle
//      STATUS  PRELIMINARY
#include "Stroika/Foundation/StroikaPreComp.h"

#include <iostream>
#include <sstream>

#include "Stroika/Foundation/Characters/ToString.h"
#include "Stroika/Foundation/Containers/Concrete/DataHyperRectangle_DenseVector.h"
#include "Stroika/Foundation/Containers/Concrete/DataHyperRectangle_Sparse_stdmap.h"
#include "Stroika/Foundation/Containers/DataHyperRectangle.h"
#include "Stroika/Foundation/Debug/Assertions.h"
#include "Stroika/Foundation/Debug/Trace.h"

#include "../TestHarness/SimpleClass.h"
#include "../TestHarness/TestHarness.h"

using namespace Stroika;
using namespace Stroika::Foundation;
using namespace Stroika::Foundation::Containers;

namespace {
    void DoRegressionTests_ ()
    {
        {
            DataHyperRectangle2<int> x = Concrete::DataHyperRectangle_DenseVector<int, size_t, size_t>{3, 4};
            Verify (x.GetAt (2, 2) == 0);

            for (auto t : x) {
                int breakhere = 1;
                int b2        = 3;
            }
        }
        {
            DataHyperRectangle2<int> x = Concrete::DataHyperRectangle_Sparse_stdmap<int, size_t, size_t>{};
            Verify (x.GetAt (2, 2) == 0);

            for (auto t : x) {
                int breakhere = 1;
                int b2        = 3;
            }

            x.SetAt (2, 2, 4);

            for (auto t : x) {
                int breakhere = 1;
                int b2        = 3;
            }
        }
    }
}

int main (int argc, const char* argv[])
{
    Stroika::TestHarness::Setup ();
    return Stroika::TestHarness::PrintPassOrFail (DoRegressionTests_);
}
<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2020.  All rights reserved
 */
//  TEST    Foundation::Execution::ProcessRunner
#include "Stroika/Foundation/StroikaPreComp.h"

#include "Stroika/Foundation/Debug/Trace.h"
#include "Stroika/Foundation/Execution/ProcessRunner.h"
#if qPlatform_POSIX
#include "Stroika/Foundation/Execution/SignalHandlers.h"
#endif
#include "Stroika/Foundation/Execution/Sleep.h"
#include "Stroika/Foundation/Streams/MemoryStream.h"
#include "Stroika/Foundation/Streams/SharedMemoryStream.h"

#include "../TestHarness/TestHarness.h"

using std::byte;

using namespace Stroika::Foundation;
using namespace Stroika::Foundation::Execution;

using Characters::String;

namespace {
    void RegressionTest1_ ()
    {
        Debug::TraceContextBumper        ctx{L"RegressionTest1_"};
        Streams::MemoryStream<byte>::Ptr myStdOut = Streams::MemoryStream<byte>::New ();
        // quickie about to test..
        ProcessRunner pr (L"echo hi mom", nullptr, myStdOut);
        pr.Run ();
    }
    void RegressionTest2_ ()
    {
        Debug::TraceContextBumper        ctx{L"RegressionTest2_"};
        Streams::MemoryStream<byte>::Ptr myStdOut = Streams::MemoryStream<byte>::New ();
        // quickie about to test..
        ProcessRunner pr (L"echo hi mom");
        String        out = pr.Run (L"");
        VerifyTestResult (out.Trim () == L"hi mom");
    }
    void RegressionTest3_Pipe_ ()
    {
        Debug::TraceContextBumper        ctx{L"RegressionTest3_Pipe_"};
        Streams::MemoryStream<byte>::Ptr myStdOut = Streams::MemoryStream<byte>::New ();
        ProcessRunner                    pr1 (L"echo hi mom");
        Streams::MemoryStream<byte>::Ptr pipe = Streams::MemoryStream<byte>::New ();
        ProcessRunner                    pr2 (L"cat");
        pr1.SetStdOut (pipe);
        pr2.SetStdIn (pipe);

        Streams::MemoryStream<byte>::Ptr pr2Out = Streams::MemoryStream<byte>::New ();
        pr2.SetStdOut (pr2Out);

        pr1.Run ();
        pr2.Run ();

        String out = String::FromUTF8 (pr2Out.As<string> ());

        VerifyTestResult (out.Trim () == L"hi mom");
    }
    void RegressionTest4_DocSample_ ()
    {
        Debug::TraceContextBumper ctx{L"RegressionTest4_DocSample_"};
        // cat doesn't exist on windows (without cygwin or some such) - but the regression test code depends on that anyhow
        // so this should be OK for now... -- LGP 2017-06-31
        Memory::BLOB                     kData_{Memory::BLOB::Raw ("this is a test")};
        Streams::MemoryStream<byte>::Ptr processStdIn  = Streams::MemoryStream<byte>::New (kData_);
        Streams::MemoryStream<byte>::Ptr processStdOut = Streams::MemoryStream<byte>::New ();
        ProcessRunner                    pr (L"cat", processStdIn, processStdOut);
        pr.Run ();
        VerifyTestResult (processStdOut.ReadAll () == kData_);
    }
}

namespace {
    namespace LargeDataSentThroughPipe_Test5_ {
        namespace Private_ {
            const Memory::BLOB k1K_   = Memory::BLOB::Raw ("0123456789abcdef").Repeat (1024 / 16);
            const Memory::BLOB k1MB_  = k1K_.Repeat (1024);
            const Memory::BLOB k16MB_ = k1MB_.Repeat (16);

            void SingleProcessLargeDataSend_ ()
            {
                /*
                 *  "Valgrind's memory management: out of memory:"
                 *  This only happens with DEBUG builds and valgrind/helgrind. So run with less memory used, and it works better.
                 */
                Memory::BLOB                     testBLOB = (Debug::IsRunningUnderValgrind () && qDebug) ? k1K_ : k16MB_;
                Streams::MemoryStream<byte>::Ptr myStdIn  = Streams::MemoryStream<byte>::New (testBLOB);
                Streams::MemoryStream<byte>::Ptr myStdOut = Streams::MemoryStream<byte>::New ();
                ProcessRunner                    pr (L"cat", myStdIn, myStdOut);
                pr.Run ();
                VerifyTestResult (myStdOut.ReadAll () == testBLOB);
            }
        }
        void DoTests ()
        {
            Debug::TraceContextBumper ctx{L"LargeDataSentThroughPipe_Test5_::DoTests"};
            Private_::SingleProcessLargeDataSend_ ();
        }
    }
}

namespace {
    namespace LargeDataSentThroughPipeBackground_Test6_ {
        namespace Private_ {
            const Memory::BLOB k1K_   = Memory::BLOB::Raw ("0123456789abcdef").Repeat (1024 / 16);
            const Memory::BLOB k1MB_  = k1K_.Repeat (1024);
            const Memory::BLOB k16MB_ = k1MB_.Repeat (16);

            void SingleProcessLargeDataSend_ ()
            {
                Assert (k1MB_.size () == 1024 * 1024);
                Streams::SharedMemoryStream<byte>::Ptr myStdIn  = Streams::SharedMemoryStream<byte>::New (); // note must use SharedMemoryStream cuz we want to distinguish EOF from no data written yet
                Streams::SharedMemoryStream<byte>::Ptr myStdOut = Streams::SharedMemoryStream<byte>::New ();
                ProcessRunner                          pr (L"cat", myStdIn, myStdOut);
                ProcessRunner::BackgroundProcess       bg = pr.RunInBackground ();
                Execution::Sleep (1);
                VerifyTestResult (not myStdOut.ReadNonBlocking ().has_value ()); // sb no data available, but NOT EOF
                /*
                 *  "Valgrind's memory management: out of memory:"
                 *  This only happens with DEBUG builds and valgrind/helgrind. So run with less memory used, and it works better.
                 */
                Memory::BLOB testBLOB = (Debug::IsRunningUnderValgrind () && qDebug) ? k1K_ : k16MB_;
                myStdIn.Write (testBLOB);
                myStdIn.CloseWrite (); // so cat process can finish
                bg.WaitForDone ();
                myStdOut.CloseWrite (); // one process done, no more writes to this stream
                VerifyTestResult (myStdOut.ReadAll () == testBLOB);
            }
        }
        void DoTests ()
        {
            Debug::TraceContextBumper ctx{L"LargeDataSentThroughPipeBackground_Test6_::DoTests"};
            Private_::SingleProcessLargeDataSend_ ();
        }
    }
}

void RegressionTes7_FaledRun_ ()
{
    Debug::TraceContextBumper ctx{L"RegressionTes7_FaledRun_"};
    try {
        ProcessRunner pr (L"mount /fasdkfjasdfjasdkfjasdklfjasldkfjasdfkj /dadsf/a/sdf/asdf//");
        pr.Run ();
        VerifyTestResult (false);
    }
    catch (...) {
        DbgTrace (L"got failure msg: %s", Characters::ToString (current_exception ()).c_str ());
    }
}

namespace {

    void DoRegressionTests_ ()
    {
        Debug::TraceContextBumper ctx{L"DoRegressionTests_"};
#if qPlatform_POSIX
        // Many performance instruments use pipes
        // @todo - REVIEW IF REALLY NEEDED AND WHY? SO LONG AS NO FAIL SHOULDNT BE?
        //  --LGP 2014-02-05
        Execution::SignalHandlerRegistry::Get ().SetSignalHandlers (SIGPIPE, Execution::SignalHandlerRegistry::kIGNORED);
#endif
        RegressionTest1_ ();
        RegressionTest2_ ();
        RegressionTest3_Pipe_ ();
        RegressionTest4_DocSample_ ();
        LargeDataSentThroughPipe_Test5_::DoTests ();
        LargeDataSentThroughPipeBackground_Test6_::DoTests ();
        RegressionTes7_FaledRun_ ();
    }
}

int main ([[maybe_unused]] int argc, [[maybe_unused]] const char* argv[])
{
    Stroika::TestHarness::Setup ();
    return Stroika::TestHarness::PrintPassOrFail (DoRegressionTests_);
}
<commit_msg>note about new bug https://stroika.atlassian.net/browse/STK-713<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2020.  All rights reserved
 */
//  TEST    Foundation::Execution::ProcessRunner
#include "Stroika/Foundation/StroikaPreComp.h"

#include "Stroika/Foundation/Debug/Trace.h"
#include "Stroika/Foundation/Execution/ProcessRunner.h"
#if qPlatform_POSIX
#include "Stroika/Foundation/Execution/SignalHandlers.h"
#endif
#include "Stroika/Foundation/Execution/Sleep.h"
#include "Stroika/Foundation/Streams/MemoryStream.h"
#include "Stroika/Foundation/Streams/SharedMemoryStream.h"

#include "../TestHarness/TestHarness.h"

using std::byte;

using namespace Stroika::Foundation;
using namespace Stroika::Foundation::Execution;

using Characters::String;

namespace {
    void RegressionTest1_ ()
    {
        Debug::TraceContextBumper        ctx{L"RegressionTest1_"};
        Streams::MemoryStream<byte>::Ptr myStdOut = Streams::MemoryStream<byte>::New ();
        // quickie about to test..
        ProcessRunner pr (L"echo hi mom", nullptr, myStdOut);
        pr.Run ();
    }
    void RegressionTest2_ ()
    {
        Debug::TraceContextBumper        ctx{L"RegressionTest2_"};
        Streams::MemoryStream<byte>::Ptr myStdOut = Streams::MemoryStream<byte>::New ();
        // quickie about to test..
        ProcessRunner pr (L"echo hi mom");
        String        out = pr.Run (L"");
        VerifyTestResult (out.Trim () == L"hi mom");
    }
    void RegressionTest3_Pipe_ ()
    {
        Debug::TraceContextBumper        ctx{L"RegressionTest3_Pipe_"};
        Streams::MemoryStream<byte>::Ptr myStdOut = Streams::MemoryStream<byte>::New ();
        ProcessRunner                    pr1 (L"echo hi mom");
        Streams::MemoryStream<byte>::Ptr pipe = Streams::MemoryStream<byte>::New ();
        ProcessRunner                    pr2 (L"cat");
        pr1.SetStdOut (pipe);
        pr2.SetStdIn (pipe);

        Streams::MemoryStream<byte>::Ptr pr2Out = Streams::MemoryStream<byte>::New ();
        pr2.SetStdOut (pr2Out);

        pr1.Run ();
        pr2.Run ();

        String out = String::FromUTF8 (pr2Out.As<string> ());

        VerifyTestResult (out.Trim () == L"hi mom");
    }
    void RegressionTest4_DocSample_ ()
    {
        Debug::TraceContextBumper ctx{L"RegressionTest4_DocSample_"};
        // cat doesn't exist on windows (without cygwin or some such) - but the regression test code depends on that anyhow
        // so this should be OK for now... -- LGP 2017-06-31
        Memory::BLOB                     kData_{Memory::BLOB::Raw ("this is a test")};
        Streams::MemoryStream<byte>::Ptr processStdIn  = Streams::MemoryStream<byte>::New (kData_);
        Streams::MemoryStream<byte>::Ptr processStdOut = Streams::MemoryStream<byte>::New ();
        ProcessRunner                    pr (L"cat", processStdIn, processStdOut);
        pr.Run ();
        VerifyTestResult (processStdOut.ReadAll () == kData_);
    }
}

namespace {
    namespace LargeDataSentThroughPipe_Test5_ {
        namespace Private_ {
            const Memory::BLOB k1K_   = Memory::BLOB::Raw ("0123456789abcdef").Repeat (1024 / 16);
            const Memory::BLOB k1MB_  = k1K_.Repeat (1024);
            const Memory::BLOB k16MB_ = k1MB_.Repeat (16);

            void SingleProcessLargeDataSend_ ()
            {
                /*
                 *  "Valgrind's memory management: out of memory:"
                 *  This only happens with DEBUG builds and valgrind/helgrind. So run with less memory used, and it works better.
                 *
                 *  @see https://stroika.atlassian.net/browse/STK-713 if you see hang here
                 */
                Memory::BLOB                     testBLOB = (Debug::IsRunningUnderValgrind () && qDebug) ? k1K_ : k16MB_;
                Streams::MemoryStream<byte>::Ptr myStdIn  = Streams::MemoryStream<byte>::New (testBLOB);
                Streams::MemoryStream<byte>::Ptr myStdOut = Streams::MemoryStream<byte>::New ();
                ProcessRunner                    pr (L"cat", myStdIn, myStdOut);
                pr.Run ();
                VerifyTestResult (myStdOut.ReadAll () == testBLOB);
            }
        }
        void DoTests ()
        {
            Debug::TraceContextBumper ctx{L"LargeDataSentThroughPipe_Test5_::DoTests"};
            Private_::SingleProcessLargeDataSend_ ();
        }
    }
}

namespace {
    namespace LargeDataSentThroughPipeBackground_Test6_ {
        namespace Private_ {
            const Memory::BLOB k1K_   = Memory::BLOB::Raw ("0123456789abcdef").Repeat (1024 / 16);
            const Memory::BLOB k1MB_  = k1K_.Repeat (1024);
            const Memory::BLOB k16MB_ = k1MB_.Repeat (16);

            void SingleProcessLargeDataSend_ ()
            {
                Assert (k1MB_.size () == 1024 * 1024);
                Streams::SharedMemoryStream<byte>::Ptr myStdIn  = Streams::SharedMemoryStream<byte>::New (); // note must use SharedMemoryStream cuz we want to distinguish EOF from no data written yet
                Streams::SharedMemoryStream<byte>::Ptr myStdOut = Streams::SharedMemoryStream<byte>::New ();
                ProcessRunner                          pr (L"cat", myStdIn, myStdOut);
                ProcessRunner::BackgroundProcess       bg = pr.RunInBackground ();
                Execution::Sleep (1);
                VerifyTestResult (not myStdOut.ReadNonBlocking ().has_value ()); // sb no data available, but NOT EOF
                /*
                 *  "Valgrind's memory management: out of memory:"
                 *  This only happens with DEBUG builds and valgrind/helgrind. So run with less memory used, and it works better.
                 */
                Memory::BLOB testBLOB = (Debug::IsRunningUnderValgrind () && qDebug) ? k1K_ : k16MB_;
                myStdIn.Write (testBLOB);
                myStdIn.CloseWrite (); // so cat process can finish
                bg.WaitForDone ();
                myStdOut.CloseWrite (); // one process done, no more writes to this stream
                VerifyTestResult (myStdOut.ReadAll () == testBLOB);
            }
        }
        void DoTests ()
        {
            Debug::TraceContextBumper ctx{L"LargeDataSentThroughPipeBackground_Test6_::DoTests"};
            Private_::SingleProcessLargeDataSend_ ();
        }
    }
}

void RegressionTes7_FaledRun_ ()
{
    Debug::TraceContextBumper ctx{L"RegressionTes7_FaledRun_"};
    try {
        ProcessRunner pr (L"mount /fasdkfjasdfjasdkfjasdklfjasldkfjasdfkj /dadsf/a/sdf/asdf//");
        pr.Run ();
        VerifyTestResult (false);
    }
    catch (...) {
        DbgTrace (L"got failure msg: %s", Characters::ToString (current_exception ()).c_str ());
    }
}

namespace {

    void DoRegressionTests_ ()
    {
        Debug::TraceContextBumper ctx{L"DoRegressionTests_"};
#if qPlatform_POSIX
        // Many performance instruments use pipes
        // @todo - REVIEW IF REALLY NEEDED AND WHY? SO LONG AS NO FAIL SHOULDNT BE?
        //  --LGP 2014-02-05
        Execution::SignalHandlerRegistry::Get ().SetSignalHandlers (SIGPIPE, Execution::SignalHandlerRegistry::kIGNORED);
#endif
        RegressionTest1_ ();
        RegressionTest2_ ();
        RegressionTest3_Pipe_ ();
        RegressionTest4_DocSample_ ();
        LargeDataSentThroughPipe_Test5_::DoTests ();
        LargeDataSentThroughPipeBackground_Test6_::DoTests ();
        RegressionTes7_FaledRun_ ();
    }
}

int main ([[maybe_unused]] int argc, [[maybe_unused]] const char* argv[])
{
    Stroika::TestHarness::Setup ();
    return Stroika::TestHarness::PrintPassOrFail (DoRegressionTests_);
}
<|endoftext|>


<commit_before>#include "led.h"
#include "flasher.h"
#include "const.h"
#include "logger.h"
#include <Arduino.h>

//Array keeping track of states
uint8_t states[NUMBER_OF_BITS];

unsigned char led_flashingCounter = 0;

void led_setup() {
  pinMode(P_LED_VCC, OUTPUT);
  pinMode(P_LED_DATA, OUTPUT);
  pinMode(P_LED_CLOCK, OUTPUT);
  pinMode(P_LED_LATCH, OUTPUT);
}

void led_shiftOut() {
  //Latch Low. VCC high
  digitalWrite(P_LED_VCC, HIGH);
  digitalWrite(P_LED_LATCH, LOW);

  //Shift out
  for (uint8_t i = NUMBER_OF_BITS; i <= NUMBER_OF_BITS; i--)  {
    switch (states[i]) {
      case LED_STATE_OFF:
        digitalWrite(P_LED_DATA, LOW);
        break;
      case LED_STATE_ON:
        digitalWrite(P_LED_DATA, HIGH);
        break;
      case LED_STATE_FLASHING:
        flashed = true;
        digitalWrite(P_LED_DATA, flashingCurrentState);
        break;
    }

    //Clock
    digitalWrite(P_LED_CLOCK, HIGH);
    digitalWrite(P_LED_CLOCK, LOW);
  }

  //If data is left on high drop to low, so that the final output voltage is not altered
  digitalWrite(P_LED_DATA, LOW);

  //Latch high. VCC adjust to two volts
  digitalWrite(P_LED_LATCH, HIGH);
  analogWrite(P_LED_VCC, LED_VCC_PWM);

}

void led_setState(uint8_t led, uint8_t state) {
  //If we have a flashing led turn on. The thread will automatically turn off if no leds are flashing.
  if (state == LED_STATE_FLASHING) {
    flasher_thread.enabled = true;
  }

  states[led] = state;
}

<commit_msg>Add log statement<commit_after>#include "led.h"
#include "flasher.h"
#include "const.h"
#include "logger.h"
#include <Arduino.h>

//Array keeping track of states
uint8_t states[NUMBER_OF_BITS];

unsigned char led_flashingCounter = 0;

void led_setup() {
  pinMode(P_LED_VCC, OUTPUT);
  pinMode(P_LED_DATA, OUTPUT);
  pinMode(P_LED_CLOCK, OUTPUT);
  pinMode(P_LED_LATCH, OUTPUT);
}

void led_shiftOut() {
  //Latch Low. VCC high
  digitalWrite(P_LED_VCC, HIGH);
  digitalWrite(P_LED_LATCH, LOW);

  //Shift out
  for (uint8_t i = NUMBER_OF_BITS; i <= NUMBER_OF_BITS; i--)  {
    switch (states[i]) {
      case LED_STATE_OFF:
        digitalWrite(P_LED_DATA, LOW);
        break;
      case LED_STATE_ON:
        digitalWrite(P_LED_DATA, HIGH);
        break;
      case LED_STATE_FLASHING:
        flashed = true;
        digitalWrite(P_LED_DATA, flashingCurrentState);
        break;
    }

    //Clock
    digitalWrite(P_LED_CLOCK, HIGH);
    digitalWrite(P_LED_CLOCK, LOW);
  }

  //If data is left on high drop to low, so that the final output voltage is not altered
  digitalWrite(P_LED_DATA, LOW);

  //Latch high. VCC adjust to two volts
  digitalWrite(P_LED_LATCH, HIGH);
  analogWrite(P_LED_VCC, LED_VCC_PWM);

}

void led_setState(uint8_t led, uint8_t state) {
  logger(LOGGER_TYPE_INFO, "led", "Set led number " + String(led) + " to state " + String(state));

  //If we have a flashing led turn on. The thread will automatically turn off if no leds are flashing.
  if (state == LED_STATE_FLASHING) {
    flasher_thread.enabled = true;
  }

  states[led] = state;
}

<|endoftext|>


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

/* Author: Wim Meeussen */

#include "urdf_import.hpp"
#include "urdf_compatibility.h"
#include <fstream>
#include <kdl/tree.hpp>
#include <kdl/jntarray.hpp>
#include <tinyxml.h>

using namespace std;
using namespace KDL;

namespace kdl_format_io{

void printTree(urdf::ConstLinkPtr link,int level = 0)
{
  level+=2;
  int count = 0;
  for (urdf::LinkVector::const_iterator child = link->child_links.begin(); child != link->child_links.end(); child++)
  {
    if (*child)
    {
      for(int j=0;j<level;j++) std::cout << "  "; //indent
      std::cout << "child(" << (count++)+1 << "):  " << (*child)->name  << std::endl;
      // first grandchild
      printTree(*child,level);
    }
    else
    {
      for(int j=0;j<level;j++) std::cout << " "; //indent
      std::cout << "root link: " << link->name << " has a null child!" << *child << std::endl;
    }
  }

}

// construct vector
Vector toKdl(urdf::Vector3 v)
{
  return Vector(v.x, v.y, v.z);
}

// construct rotation
Rotation toKdl(urdf::Rotation r)
{
  return Rotation::Quaternion(r.x, r.y, r.z, r.w);
}

// construct pose
Frame toKdl(urdf::Pose p)
{
  return Frame(toKdl(p.rotation), toKdl(p.position));
}

// construct joint
Joint toKdl(urdf::JointPtr jnt)
{
  Frame F_parent_jnt = toKdl(jnt->parent_to_joint_origin_transform);

  switch (jnt->type){
  case urdf::Joint::FIXED:{
    return Joint(jnt->name, Joint::None);
  }
  case urdf::Joint::REVOLUTE:{
    Vector axis = toKdl(jnt->axis);
    return Joint(jnt->name, F_parent_jnt.p, F_parent_jnt.M * axis, Joint::RotAxis);
  }
  case urdf::Joint::CONTINUOUS:{
    Vector axis = toKdl(jnt->axis);
    return Joint(jnt->name, F_parent_jnt.p, F_parent_jnt.M * axis, Joint::RotAxis);
  }
  case urdf::Joint::PRISMATIC:{
    Vector axis = toKdl(jnt->axis);
    return Joint(jnt->name, F_parent_jnt.p, F_parent_jnt.M * axis, Joint::TransAxis);
  }
  default:{
    std::cerr << "Converting unknown joint type of joint " << jnt->name << " into a fixed joint" << std::endl;
    return Joint(jnt->name, Joint::None);
  }
  }
  return Joint();
}

// construct inertia
RigidBodyInertia toKdl(urdf::InertialPtr i)
{
  Frame origin = toKdl(i->origin);

  // the mass is frame indipendent
  double kdl_mass = i->mass;

  // kdl and urdf both specify the com position in the reference frame of the link
  Vector kdl_com = origin.p;

  // kdl specifies the inertia matrix in the reference frame of the link,
  // while the urdf specifies the inertia matrix in the inertia reference frame
  RotationalInertia urdf_inertia =
    RotationalInertia(i->ixx, i->iyy, i->izz, i->ixy, i->ixz, i->iyz);

  // Rotation operators are not defined for rotational inertia,
  // so we use the RigidBodyInertia operators (with com = 0) as a workaround
  RigidBodyInertia kdl_inertia_wrt_com_workaround =
    origin.M *RigidBodyInertia(0, Vector::Zero(), urdf_inertia);

  // Note that the RigidBodyInertia constructor takes the 3d inertia wrt the com
  // while the getRotationalInertia method returns the 3d inertia wrt the frame origin
  // (but having com = Vector::Zero() in kdl_inertia_wrt_com_workaround they match)
  RotationalInertia kdl_inertia_wrt_com =
    kdl_inertia_wrt_com_workaround.getRotationalInertia();

  return RigidBodyInertia(kdl_mass,kdl_com,kdl_inertia_wrt_com);
}

// recursive function to walk through tree
bool addChildrenToTree(urdf::LinkPtr root, Tree& tree)
{
  urdf::LinkVector children = root->child_links;
  //std::cerr << "[INFO] Link " << root->name << " had " << children.size() << " children" << std::endl;

  // constructs the optional inertia
  RigidBodyInertia inert(0);
  if (root->inertial)
    inert = toKdl(root->inertial);

  // constructs the kdl joint
  Joint jnt = toKdl(root->parent_joint);

  // construct the kdl segment
  Segment sgm(root->name, jnt, toKdl(root->parent_joint->parent_to_joint_origin_transform), inert);

  // add segment to tree
  tree.addSegment(sgm, root->parent_joint->parent_link_name);

  // recurslively add all children
  for (size_t i=0; i<children.size(); i++){
    if (!addChildrenToTree(children[i], tree))
      return false;
  }
  return true;
}

bool treeFromUrdfFile(const string& file, Tree& tree,const bool consider_root_link_inertia)
{
    ifstream ifs(file.c_str());
    std::string xml_string( (std::istreambuf_iterator<char>(ifs) ),
                       (std::istreambuf_iterator<char>()    ) );

    return treeFromUrdfString(xml_string,tree,consider_root_link_inertia);
}

/*
bool treeFromParam(const string& param, Tree& tree)
{
  urdf::ModelInterface robot_model;
  if (!robot_model.initParam(param)){
    logError("Could not generate robot model");
    return false;
  }
  return treeFromUrdfModel(robot_model, tree);
}
*/

int print_tree(urdf::ModelInterfacePtr & robot) {
std::cout << "robot name is: " << robot->getName() << std::endl;

  // get info from parser
  std::cout << "---------- Successfully Parsed XML ---------------" << std::endl;
  // get root link
  urdf::ConstLinkPtr root_link=robot->getRoot();
  if (!root_link) return -1;

  std::cout << "root Link: " << root_link->name << " has " << root_link->child_links.size() << " child(ren)" << std::endl;

  // print entire tree
  printTree(root_link);

  return 0;
}

bool treeFromUrdfString(const string& xml, Tree& tree, const bool consider_root_link_inertia)
{
  urdf::ModelInterfacePtr urdf_model;
  urdf_model = urdf::parseURDF(xml);
  if( !urdf_model )
  {
      std::cerr << "[ERR] Could not parse string to urdf::ModelInterface" << std::endl;
      return false;
  }
  return treeFromUrdfModel(*urdf_model,tree,consider_root_link_inertia);
}

/*
bool treeFromUrdfXml(TiXmlDocument *xml_doc, Tree& tree)
{
  urdf::ModelInterfacePtr robot_model;
  robot_model = urdf::parseURDF(
  if (!robot_model.parse(xml_doc)){
    logError("Could not generate robot model");
    return false;
  }
  return treeFromUrdfModel(robot_model, tree);
}*/

bool treeFromUrdfModel(const urdf::ModelInterface& robot_model, Tree& tree, const bool consider_root_link_inertia)
{
  if (consider_root_link_inertia) {
    //For giving a name to the root of KDL using the robot name,
    //as it is not used elsewhere in the KDL tree
    std::string fake_root_name = "__kdl_import__" + robot_model.getName()+"__fake_root__";
    std::string fake_root_fixed_joint_name = "__kdl_import__" + robot_model.getName()+"__fake_root_fixed_joint__";

    tree = Tree(fake_root_name);

   const urdf::ConstLinkPtr root = robot_model.getRoot();

    // constructs the optional inertia
    RigidBodyInertia inert(0);
    if (root->inertial)
      inert = toKdl(root->inertial);

    // constructs the kdl joint
    Joint jnt = Joint(fake_root_fixed_joint_name, Joint::None);

    // construct the kdl segment
    Segment sgm(root->name, jnt, Frame::Identity(), inert);

    // add segment to tree
    tree.addSegment(sgm, fake_root_name);

  } else {
    tree = Tree(robot_model.getRoot()->name);

    // warn if root link has inertia. KDL does not support this
    if (robot_model.getRoot()->inertial)
      std::cerr << "The root link " << robot_model.getRoot()->name <<
                   " has an inertia specified in the URDF, but KDL does not support a root link with an inertia.  As a workaround, you can add an extra dummy link to your URDF." << std::endl;
  }

  //  add all children
  for (size_t i=0; i<robot_model.getRoot()->child_links.size(); i++)
    if (!addChildrenToTree(robot_model.getRoot()->child_links[i], tree))
      return false;

  return true;
}

bool jointPosLimitsFromUrdfFile(const std::string& file,
                             std::vector<std::string> & joint_names,
                             KDL::JntArray & min,
                             KDL::JntArray & max)
{
    ifstream ifs(file.c_str());
    std::string xml_string( (std::istreambuf_iterator<char>(ifs) ),
                       (std::istreambuf_iterator<char>()    ) );

    return jointPosLimitsFromUrdfString(xml_string,joint_names,min,max);
}

bool jointPosLimitsFromUrdfString(const std::string& urdf_xml,
                               std::vector<std::string> & joint_names,
                               KDL::JntArray & min,
                               KDL::JntArray & max)
{
  urdf::ModelInterfacePtr urdf_model;
  urdf_model = urdf::parseURDF(urdf_xml);
  if( !urdf_model )
  {
      std::cerr << "[ERR] Could not parse string to urdf::ModelInterface" << std::endl;
      return false;
  }
  return jointPosLimitsFromUrdfModel(*urdf_model,joint_names,min,max);
}

bool jointPosLimitsFromUrdfModel(const urdf::ModelInterface& robot_model,
                              std::vector<std::string> & joint_names,
                              KDL::JntArray & min,
                              KDL::JntArray & max)
{
    int nrOfJointsWithLimits=0;
    for (urdf::JointPtrMap::const_iterator it=robot_model.joints_.begin(); it!=robot_model.joints_.end(); ++it)
    {
        if( it->second->type == urdf::Joint::REVOLUTE ||
            it->second->type == urdf::Joint::PRISMATIC )
        {
            nrOfJointsWithLimits++;
        }
    }

    joint_names.resize(nrOfJointsWithLimits);
    min.resize(nrOfJointsWithLimits);
    max.resize(nrOfJointsWithLimits);

    int index =0;
    for (urdf::JointPtrMap::const_iterator it=robot_model.joints_.begin(); it!=robot_model.joints_.end(); ++it)
    {
        if( it->second->type == urdf::Joint::REVOLUTE ||
            it->second->type == urdf::Joint::PRISMATIC )
        {
            joint_names[index] = (it->first);
            min(index) = it->second->limits->lower;
            max(index) = it->second->limits->upper;
            index++;
        }
    }

    if( index != nrOfJointsWithLimits )
    {
        std::cerr << "[ERR] kdl_format_io error in jointPosLimitsFromUrdfModel function" << std::endl;
        return false;
    }

    return true;
}

bool framesFromKDLTree(const KDL::Tree& tree,
                       std::vector<std::string>& framesNames,
                       std::vector<std::string>& parentLinkNames)
{
    framesNames.clear();
    parentLinkNames.clear();

    KDL::SegmentMap::iterator seg;
    KDL::SegmentMap segs;
    KDL::SegmentMap::const_iterator root_seg;
    root_seg = tree.getRootSegment();
    segs = tree.getSegments();
    for( seg = segs.begin(); seg != segs.end(); seg++ )
    {
        if( seg->second.children.size() == 0 &&
            seg->second.segment.getJoint().getType() == KDL::Joint::None &&
            seg->second.segment.getInertia().getMass() == 0.0 )
        {
            std::string frameName = seg->second.segment.getName();
            std::string parentLinkName = seg->second.parent->second.segment.getName();
            framesNames.push_back(frameName);
            parentLinkNames.push_back(parentLinkName);
        }
    }

    return true;
}

}

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

/* Author: Wim Meeussen */

#include "urdf_import.hpp"
#include "urdf_compatibility.h"
#include <fstream>
#include <kdl/tree.hpp>
#include <kdl/jntarray.hpp>
#include <tinyxml.h>

using namespace std;
using namespace KDL;

namespace kdl_format_io{

void printTree(urdf::ConstLinkPtr link,int level = 0)
{
  level+=2;
  int count = 0;
  for (urdf::LinkVector::const_iterator child = link->child_links.begin(); child != link->child_links.end(); child++)
  {
    if (*child)
    {
      for(int j=0;j<level;j++) std::cout << "  "; //indent
      std::cout << "child(" << (count++)+1 << "):  " << (*child)->name  << std::endl;
      // first grandchild
      printTree(*child,level);
    }
    else
    {
      for(int j=0;j<level;j++) std::cout << " "; //indent
      std::cout << "root link: " << link->name << " has a null child!" << *child << std::endl;
    }
  }

}

// construct vector
Vector toKdl(urdf::Vector3 v)
{
  return Vector(v.x, v.y, v.z);
}

// construct rotation
Rotation toKdl(urdf::Rotation r)
{
  return Rotation::Quaternion(r.x, r.y, r.z, r.w);
}

// construct pose
Frame toKdl(urdf::Pose p)
{
  return Frame(toKdl(p.rotation), toKdl(p.position));
}

// construct joint
Joint toKdl(urdf::JointPtr jnt)
{
  Frame F_parent_jnt = toKdl(jnt->parent_to_joint_origin_transform);

  switch (jnt->type){
  case urdf::Joint::FIXED:{
    return Joint(jnt->name, Joint::None);
  }
  case urdf::Joint::REVOLUTE:{
    Vector axis = toKdl(jnt->axis);
    return Joint(jnt->name, F_parent_jnt.p, F_parent_jnt.M * axis, Joint::RotAxis);
  }
  case urdf::Joint::CONTINUOUS:{
    Vector axis = toKdl(jnt->axis);
    return Joint(jnt->name, F_parent_jnt.p, F_parent_jnt.M * axis, Joint::RotAxis);
  }
  case urdf::Joint::PRISMATIC:{
    Vector axis = toKdl(jnt->axis);
    return Joint(jnt->name, F_parent_jnt.p, F_parent_jnt.M * axis, Joint::TransAxis);
  }
  default:{
    std::cerr << "Converting unknown joint type of joint " << jnt->name << " into a fixed joint" << std::endl;
    return Joint(jnt->name, Joint::None);
  }
  }
  return Joint();
}

// construct inertia
RigidBodyInertia toKdl(urdf::InertialPtr i)
{
  Frame origin = toKdl(i->origin);

  // the mass is frame indipendent
  double kdl_mass = i->mass;

  // kdl and urdf both specify the com position in the reference frame of the link
  Vector kdl_com = origin.p;

  // kdl specifies the inertia matrix in the reference frame of the link,
  // while the urdf specifies the inertia matrix in the inertia reference frame
  RotationalInertia urdf_inertia =
    RotationalInertia(i->ixx, i->iyy, i->izz, i->ixy, i->ixz, i->iyz);

  // Rotation operators are not defined for rotational inertia,
  // so we use the RigidBodyInertia operators (with com = 0) as a workaround
  RigidBodyInertia kdl_inertia_wrt_com_workaround =
    origin.M *RigidBodyInertia(0, Vector::Zero(), urdf_inertia);

  // Note that the RigidBodyInertia constructor takes the 3d inertia wrt the com
  // while the getRotationalInertia method returns the 3d inertia wrt the frame origin
  // (but having com = Vector::Zero() in kdl_inertia_wrt_com_workaround they match)
  RotationalInertia kdl_inertia_wrt_com =
    kdl_inertia_wrt_com_workaround.getRotationalInertia();

  return RigidBodyInertia(kdl_mass,kdl_com,kdl_inertia_wrt_com);
}

// recursive function to walk through tree
bool addChildrenToTree(urdf::LinkPtr root, Tree& tree)
{
  urdf::LinkVector children = root->child_links;
  //std::cerr << "[INFO] Link " << root->name << " had " << children.size() << " children" << std::endl;

  // constructs the optional inertia
  RigidBodyInertia inert(0);
  if (root->inertial)
    inert = toKdl(root->inertial);

  // constructs the kdl joint
  Joint jnt = toKdl(root->parent_joint);

  // construct the kdl segment
  Segment sgm(root->name, jnt, toKdl(root->parent_joint->parent_to_joint_origin_transform), inert);

  // add segment to tree
  tree.addSegment(sgm, root->parent_joint->parent_link_name);

  // recurslively add all children
  for (size_t i=0; i<children.size(); i++){
    if (!addChildrenToTree(children[i], tree))
      return false;
  }
  return true;
}

bool treeFromUrdfFile(const string& file, Tree& tree,const bool consider_root_link_inertia)
{
    ifstream ifs(file.c_str());
    std::string xml_string( (std::istreambuf_iterator<char>(ifs) ),
                       (std::istreambuf_iterator<char>()    ) );

    return treeFromUrdfString(xml_string,tree,consider_root_link_inertia);
}

/*
bool treeFromParam(const string& param, Tree& tree)
{
  urdf::ModelInterface robot_model;
  if (!robot_model.initParam(param)){
    logError("Could not generate robot model");
    return false;
  }
  return treeFromUrdfModel(robot_model, tree);
}
*/

int print_tree(urdf::ModelInterfacePtr & robot) {
std::cout << "robot name is: " << robot->getName() << std::endl;

  // get info from parser
  std::cout << "---------- Successfully Parsed XML ---------------" << std::endl;
  // get root link
  urdf::ConstLinkPtr root_link=robot->getRoot();
  if (!root_link) return -1;

  std::cout << "root Link: " << root_link->name << " has " << root_link->child_links.size() << " child(ren)" << std::endl;

  // print entire tree
  printTree(root_link);

  return 0;
}

bool treeFromUrdfString(const string& xml, Tree& tree, const bool consider_root_link_inertia)
{
  urdf::ModelInterfacePtr urdf_model;
  urdf_model = urdf::parseURDF(xml);
  if( !urdf_model )
  {
      std::cerr << "[ERR] Could not parse string to urdf::ModelInterface" << std::endl;
      return false;
  }
  return treeFromUrdfModel(*urdf_model,tree,consider_root_link_inertia);
}

/*
bool treeFromUrdfXml(TiXmlDocument *xml_doc, Tree& tree)
{
  urdf::ModelInterfacePtr robot_model;
  robot_model = urdf::parseURDF(
  if (!robot_model.parse(xml_doc)){
    logError("Could not generate robot model");
    return false;
  }
  return treeFromUrdfModel(robot_model, tree);
}*/

bool treeFromUrdfModel(const urdf::ModelInterface& robot_model, Tree& tree, const bool consider_root_link_inertia)
{
  if (consider_root_link_inertia) {
    //For giving a name to the root of KDL using the robot name,
    //as it is not used elsewhere in the KDL tree
    std::string fake_root_name = "__kdl_import__" + robot_model.getName()+"__fake_root__";
    std::string fake_root_fixed_joint_name = "__kdl_import__" + robot_model.getName()+"__fake_root_fixed_joint__";

    tree = Tree(fake_root_name);

   const urdf::ConstLinkPtr root = robot_model.getRoot();

    // constructs the optional inertia
    RigidBodyInertia inert(0);
    if (root->inertial)
      inert = toKdl(root->inertial);

    // constructs the kdl joint
    Joint jnt = Joint(fake_root_fixed_joint_name, Joint::None);

    // construct the kdl segment
    Segment sgm(root->name, jnt, Frame::Identity(), inert);

    // add segment to tree
    tree.addSegment(sgm, fake_root_name);

  } else {
    tree = Tree(robot_model.getRoot()->name);

    // warn if root link has inertia. KDL does not support this
    if (robot_model.getRoot()->inertial)
      std::cerr << "The root link " << robot_model.getRoot()->name <<
                   " has an inertia specified in the URDF, but KDL does not support a root link with an inertia.  As a workaround, you can add an extra dummy link to your URDF." << std::endl;
  }

  //  add all children
  for (size_t i=0; i<robot_model.getRoot()->child_links.size(); i++)
    if (!addChildrenToTree(robot_model.getRoot()->child_links[i], tree))
      return false;

  return true;
}

bool jointPosLimitsFromUrdfFile(const std::string& file,
                             std::vector<std::string> & joint_names,
                             KDL::JntArray & min,
                             KDL::JntArray & max)
{
    ifstream ifs(file.c_str());
    std::string xml_string( (std::istreambuf_iterator<char>(ifs) ),
                       (std::istreambuf_iterator<char>()    ) );

    return jointPosLimitsFromUrdfString(xml_string,joint_names,min,max);
}

bool jointPosLimitsFromUrdfString(const std::string& urdf_xml,
                               std::vector<std::string> & joint_names,
                               KDL::JntArray & min,
                               KDL::JntArray & max)
{
  urdf::ModelInterfacePtr urdf_model;
  urdf_model = urdf::parseURDF(urdf_xml);
  if( !urdf_model )
  {
      std::cerr << "[ERR] Could not parse string to urdf::ModelInterface" << std::endl;
      return false;
  }
  return jointPosLimitsFromUrdfModel(*urdf_model,joint_names,min,max);
}

bool jointPosLimitsFromUrdfModel(const urdf::ModelInterface& robot_model,
                              std::vector<std::string> & joint_names,
                              KDL::JntArray & min,
                              KDL::JntArray & max)
{
    int nrOfJointsWithLimits=0;
    for (urdf::JointPtrMap::const_iterator it=robot_model.joints_.begin(); it!=robot_model.joints_.end(); ++it)
    {
        if( it->second->type == urdf::Joint::REVOLUTE ||
            it->second->type == urdf::Joint::PRISMATIC )
        {
            nrOfJointsWithLimits++;
        }
    }

    joint_names.resize(nrOfJointsWithLimits);
    min.resize(nrOfJointsWithLimits);
    max.resize(nrOfJointsWithLimits);

    int index =0;
    for (urdf::JointPtrMap::const_iterator it=robot_model.joints_.begin(); it!=robot_model.joints_.end(); ++it)
    {
        if( it->second->type == urdf::Joint::REVOLUTE ||
            it->second->type == urdf::Joint::PRISMATIC )
        {
            joint_names[index] = (it->first);
            min(index) = it->second->limits->lower;
            max(index) = it->second->limits->upper;
            index++;
        }
    }

    if( index != nrOfJointsWithLimits )
    {
        std::cerr << "[ERR] kdl_format_io error in jointPosLimitsFromUrdfModel function" << std::endl;
        return false;
    }

    return true;
}

bool framesFromKDLTree(const KDL::Tree& tree,
                       std::vector<std::string>& framesNames,
                       std::vector<std::string>& parentLinkNames)
{
    framesNames.clear();
    parentLinkNames.clear();

    KDL::SegmentMap::iterator seg;
    KDL::SegmentMap segs;
    KDL::SegmentMap::const_iterator root_seg;
    root_seg = tree.getRootSegment();
    segs = tree.getSegments();
    for( seg = segs.begin(); seg != segs.end(); seg++ )
    {
        if( GetTreeElementChildren(seg->second).size() == 0 &&
            GetTreeElementSegment(seg->second).getJoint().getType() == KDL::Joint::None &&
            GetTreeElementSegment(seg->second).getInertia().getMass() == 0.0 )
        {
            std::string frameName = GetTreeElementSegment(seg->second).getName();
            std::string parentLinkName = GetTreeElementSegment(GetTreeElementParent(seg->second)->second).getName();
            framesNames.push_back(frameName);
            parentLinkNames.push_back(parentLinkName);
        }
    }

    return true;
}

}

<|endoftext|>


<commit_before><commit_msg>Support the ECC cipher suites added in Mac OS X 10.6.<commit_after><|endoftext|>


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

#include "crash_handler.h"

#include <gtest/gtest.h>

#include <stdlib.h>
#include <iostream>

namespace core {
namespace test {

TEST(CrashHandlerTest, HandleCrash) {
    CrashHandler crashHandler;
    crashHandler.registerHandler([] (const std::string& minidumpPath, bool succeeded) {
        if (succeeded) {
            std::cerr << "crash handled.";
        } else {
            std::cerr << "crash not handled.";
        }
    });

    EXPECT_DEATH({ int i = *((volatile int*)(0)); }, "crash handled.");
}

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

#include "crash_handler.h"

#include "core/cc/target.h"

#include <gtest/gtest.h>

#include <stdlib.h>
#include <iostream>

namespace core {
namespace test {

#if TARGET_OS != GAPID_OS_OSX // Work around for https://github.com/google/gapid/issues/1788
TEST(CrashHandlerTest, HandleCrash) {
    CrashHandler crashHandler;
    crashHandler.registerHandler([] (const std::string& minidumpPath, bool succeeded) {
        if (succeeded) {
            std::cerr << "crash handled.";
        } else {
            std::cerr << "crash not handled.";
        }
    });

    EXPECT_DEATH({ int i = *((volatile int*)(0)); }, "crash handled.");
}
#endif // TARGET_OS != GAPID_OS_OSX

} // namespace test
} // namespace core
<|endoftext|>


<commit_before>/*
 * This file is part of telepathy-accounts-kcm
 *
 * Copyright (C) 2011 Florian Reinhard <florian.reinhard@googlemail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "haze-skype-account-ui.h"

#include "skype-main-options-widget.h"
#include "skype-advanced-settings-widget.h"

HazeSkypeAccountUi::HazeSkypeAccountUi(QObject *parent)
 : AbstractAccountUi(parent)
{
    // Register supported parameters
    // Main Options
    registerSupportedParameter(QLatin1String("account"), QVariant::String);

    // Advanced Options
    registerSupportedParameter(QLatin1String("skypeout-online"), QVariant::Bool);
    registerSupportedParameter(QLatin1String("skype-sync"), QVariant::Bool);
    registerSupportedParameter(QLatin1String("check-for-updates"), QVariant::Bool);
    registerSupportedParameter(QLatin1String("reject-all-auths"), QVariant::Bool);
    registerSupportedParameter(QLatin1String("skype-autostart"), QVariant::Bool);
}

HazeSkypeAccountUi::~HazeSkypeAccountUi()
{
}

AbstractAccountParametersWidget *HazeSkypeAccountUi::mainOptionsWidget(
    ParameterEditModel *model,
    QWidget *parent) const
{
    return new SkypeMainOptionsWidget(model, parent);
}

bool HazeSkypeAccountUi::hasAdvancedOptionsWidget() const
{
    return true;
}

AbstractAccountParametersWidget *HazeSkypeAccountUi::advancedOptionsWidget(
    ParameterEditModel *model,
    QWidget *parent) const
{
    AbstractAccountParametersWidget *skypeAdvancedSettingsWidget = new SkypeAdvancedSettingsWidget(model, parent);
    return skypeAdvancedSettingsWidget;
}

#include "haze-skype-account-ui.moc"
<commit_msg>Disable advanced options widget in Haze-Skype<commit_after>/*
 * This file is part of telepathy-accounts-kcm
 *
 * Copyright (C) 2011 Florian Reinhard <florian.reinhard@googlemail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "haze-skype-account-ui.h"

#include "skype-main-options-widget.h"
#include "skype-advanced-settings-widget.h"

HazeSkypeAccountUi::HazeSkypeAccountUi(QObject *parent)
 : AbstractAccountUi(parent)
{
    // Register supported parameters
    // Main Options
    registerSupportedParameter(QLatin1String("account"), QVariant::String);

    // Advanced Options
    registerSupportedParameter(QLatin1String("skypeout-online"), QVariant::Bool);
    registerSupportedParameter(QLatin1String("skype-sync"), QVariant::Bool);
    registerSupportedParameter(QLatin1String("check-for-updates"), QVariant::Bool);
    registerSupportedParameter(QLatin1String("reject-all-auths"), QVariant::Bool);
    registerSupportedParameter(QLatin1String("skype-autostart"), QVariant::Bool);
}

HazeSkypeAccountUi::~HazeSkypeAccountUi()
{
}

AbstractAccountParametersWidget *HazeSkypeAccountUi::mainOptionsWidget(
    ParameterEditModel *model,
    QWidget *parent) const
{
    return new SkypeMainOptionsWidget(model, parent);
}

bool HazeSkypeAccountUi::hasAdvancedOptionsWidget() const
{
    return false;
}

AbstractAccountParametersWidget *HazeSkypeAccountUi::advancedOptionsWidget(
    ParameterEditModel *model,
    QWidget *parent) const
{
    AbstractAccountParametersWidget *skypeAdvancedSettingsWidget = new SkypeAdvancedSettingsWidget(model, parent);
    return skypeAdvancedSettingsWidget;
}

#include "haze-skype-account-ui.moc"
<|endoftext|>