<commit_before>/**
  * Touhou Community Reliant Automatic Patcher
  * Tasogare Frontier support plugin
  *
  * ----
  *
  * New Super Marisa Land support functions
  */

#include <thcrap.h>
#include "thcrap_tasofro.h"
#include "tfcs.h"
#include "bgm.h"
#include "cv0.h"
#include "nsml_images.h"
#include <set>

/// Detour chains
/// -------------
W32U8_DETOUR_CHAIN_DEF(GetGlyphOutline);
/// -------------

static CRITICAL_SECTION cs;
static std::set<const char*, bool(*)(const char*, const char*)> game_fallback_ignore_list([](const char *a, const char *b){ return strcmp(a, b) < 0; });

// Copy-paste of fn_for_game from patchfile.cpp
static char* fn_for_th105(const char *fn)
{
	const char *game_id = "th105";
	size_t game_id_len = strlen(game_id) + 1;
	char *full_fn;

	if (!fn) {
		return NULL;
	}
	full_fn = (char*)malloc(game_id_len + strlen(fn) + 1);

	full_fn[0] = 0; // Because strcat
	if (game_id) {
		strncpy(full_fn, game_id, game_id_len);
		strcat(full_fn, "/");
	}
	strcat(full_fn, fn);
	return full_fn;
}

json_t *th123_resolve_chain_game(const char *fn)
{
	json_t *ret = nullptr;

	// First, th105
	if (game_fallback_ignore_list.find(fn) == game_fallback_ignore_list.end()) {
		char *fn_game = fn_for_th105(fn);
		ret = resolve_chain(fn_game);
		SAFE_FREE(fn_game);
	}

	char *fn_common = fn_for_game(fn);
	const char *fn_common_ptr = fn_common ? fn_common : fn;
	json_t *th123_ret = resolve_chain(fn_common_ptr);
	if (ret && th123_ret) {
		json_array_extend(ret, th123_ret);
		json_decref(th123_ret);
	}
	else if (!ret && th123_ret) {
		ret = th123_ret;
	}
	SAFE_FREE(fn_common);
	return ret;
}

int nsml_init()
{
	if (game_id == TH_MEGAMARI) {
		patchhook_register("*.bmp", patch_bmp, get_bmp_size);
	}
	else if (game_id == TH_NSML) {
		// Increasing the file size makes the game crash.
		patchhook_register("*.cv2", patch_cv2, nullptr);
	}
	else if (game_id == TH105 || game_id == TH123) {
		patchhook_register("*.cv0", patch_cv0, nullptr);
		patchhook_register("*.cv1", patch_csv, nullptr);
		patchhook_register("*.cv2", patch_cv2, get_cv2_size);
		patchhook_register("*.dat", patch_dat_for_png, [](const char*, json_t*, size_t) -> size_t { return 0; });
		jsonvfs_game_add_map("data/csv/*/spellcard.cv1.jdiff", "spells.js");
		jsonvfs_game_add_map("data/csv/*/storyspell.cv1.jdiff", "spells.js");
	}

	if (game_id == TH105) {
		char *bgm_fn = fn_for_game("data/csv/system/music.cv1.jdiff");
		jsonvfs_add(bgm_fn, { "themes.js" }, bgm_generator);
		SAFE_FREE(bgm_fn);
	}
	else if (game_id == TH123) {
		char *bgm_fn = fn_for_game("data/csv/system/music*.cv1.jdiff");
		jsonvfs_add_map(bgm_fn, "themes.js");
		SAFE_FREE(bgm_fn);

		set_resolve_chain_game(th123_resolve_chain_game);
		json_t *list = stack_game_json_resolve("game_fallback_ignore_list.js", nullptr);
		size_t i;
		json_t *value;
		json_array_foreach(list, i, value) {
			game_fallback_ignore_list.insert(json_string_value(value));
		}
	}
	return 0;
}

int BP_nsml_file_header(x86_reg_t *regs, json_t *bp_info)
{
	// Parameters
	// ----------
	const char *filename = (const char*)json_object_get_immediate(bp_info, regs, "file_name");
	size_t fn_size = json_object_get_immediate(bp_info, regs, "fn_size");
	// ----------

	char *uFilename;
	if (fn_size) {
		uFilename = EnsureUTF8(filename, fn_size);
	}
	else {
		uFilename = EnsureUTF8(filename, strlen(filename));
	}
	CharLowerA(uFilename);

	json_t *new_bp_info = json_copy(bp_info);
	json_object_set_new(new_bp_info, "file_name", json_integer((json_int_t)uFilename));
	EnterCriticalSection(&cs);
	int ret = BP_file_header(regs, new_bp_info);
	LeaveCriticalSection(&cs);

	json_decref(new_bp_info);
	free(uFilename);
	return ret;
}

static void megamari_patch(const file_rep_t *fr, BYTE *buffer, size_t size)
{
	BYTE key = ((fr->offset >> 1) | 8) & 0xFF;
	for (unsigned int i = 0; i < size; i++) {
		buffer[i] ^= key;
	}
}

static void nsml_patch(const file_rep_t *fr, BYTE *buffer, size_t size)
{
	BYTE key = ((fr->offset >> 1) | 0x23) & 0xFF;
	for (unsigned int i = 0; i < size; i++) {
		buffer[i] ^= key;
	}
}

static void th105_patch(const file_rep_t *fr, BYTE *buffer, size_t size)
{
	nsml_patch(fr, buffer, size);
	const char *ext = PathFindExtensionA(fr->name);
	if (!strcmp(ext, ".cv0") || !strcmp(ext, ".cv1")) {
		unsigned char xorval = 0x8b;
		unsigned char xoradd = 0x71;
		unsigned char xoraddadd = 0x95;
		for (unsigned int i = 0; i < size; i++) {
			buffer[i] ^= xorval;
			xorval += xoradd;
			xoradd += xoraddadd;
		}
	}
}

int BP_nsml_read_file(x86_reg_t *regs, json_t *bp_info)
{
	// Parameters
	// ----------
	const char *file_name = (const char*)json_object_get_immediate(bp_info, regs, "file_name");
	// ----------

	// bp_info may be used by several threads at the same time, so we can't change its values.
	json_t *new_bp_info = json_deep_copy(bp_info);
	char *uFilename = nullptr;

	if (file_name) {
		uFilename = EnsureUTF8(file_name, strlen(file_name));
		CharLowerA(uFilename);
		json_object_set_new(new_bp_info, "file_name", json_integer((json_int_t)uFilename));
	}

	if (game_id == TH_MEGAMARI) {
		json_object_set_new(new_bp_info, "post_read", json_integer((json_int_t)megamari_patch));
		json_object_set_new(new_bp_info, "post_patch", json_integer((json_int_t)megamari_patch));
	}
	else if (game_id == TH105 || game_id == TH123) {
		json_object_set_new(new_bp_info, "post_read", json_integer((json_int_t)th105_patch));
		json_object_set_new(new_bp_info, "post_patch", json_integer((json_int_t)th105_patch));
	}
	else {
		json_object_set_new(new_bp_info, "post_read", json_integer((json_int_t)nsml_patch));
		json_object_set_new(new_bp_info, "post_patch", json_integer((json_int_t)nsml_patch));
	}
	int ret = BP_fragmented_read_file(regs, new_bp_info);
	json_decref(new_bp_info);
	free(uFilename);
	return ret;
}

// In th105, relying on the last open file doesn't work. So we'll use the file object instead.
int BP_th105_file_new(x86_reg_t *regs, json_t *bp_info)
{
	// Parameters
	// ----------
	const char *file_name = (const char*)json_object_get_immediate(bp_info, regs, "file_name");
	void *file_object = (void*)json_object_get_immediate(bp_info, regs, "file_object");
	// ----------

	if (!file_name || !file_object) {
		return 1;
	}
	char *uFilename = EnsureUTF8(file_name, strlen(file_name));
	CharLowerA(uFilename);
	file_rep_t *fr = file_rep_get(uFilename);
	if (fr) {
		file_rep_set_object(fr, file_object);
	}
	free(uFilename);
	return 1;
}

int BP_th105_file_delete(x86_reg_t *regs, json_t *bp_info)
{
	// Parameters
	// ----------
	void *file_object = (void*)json_object_get_immediate(bp_info, regs, "file_object");
	// ----------

	if (!file_object) {
		return 1;
	}
	file_rep_t *fr = file_rep_get_by_object(file_object);
	if (fr) {
		file_rep_set_object(fr, nullptr);
	}
	return 1;
}

int BP_th105_font_spacing(x86_reg_t *regs, json_t *bp_info)
{
	// Parameters
	// ----------
	size_t font_size     = json_object_get_immediate(bp_info, regs, "font_size");
	size_t *y_offset     = json_object_get_pointer(bp_info, regs, "y_offset");
	size_t *font_spacing = json_object_get_pointer(bp_info, regs, "font_spacing");
	// ----------

	if (!font_size) {
		return 1;
	}

	json_t *entry = json_object_numkey_get(json_object_get(bp_info, "new_y_offset"), font_size);
	if (entry && json_is_integer(entry) && y_offset) {
		*y_offset  = (size_t)json_integer_value(entry);
	}

	entry = json_object_numkey_get(json_object_get(bp_info, "new_spacing"), font_size);
	if (entry && json_is_integer(entry) && font_spacing) {
		*font_spacing = (size_t)json_integer_value(entry);
	}
	return 1;
}

DWORD WINAPI th105_GetGlyphOutlineU(HDC hdc, UINT uChar, UINT uFormat, LPGLYPHMETRICS lpgm, DWORD cbBuffer, LPVOID lpvBuffer, const MAT2 *lpmat2)
{
	uChar = CharToUTF16(uChar);

	if (uChar & 0xFFFF0000 ||
		font_has_character(hdc, uChar)) {
		// is_character_in_font won't work if the character doesn't fit into a WCHAR.
		// When it happens, we'll be optimistic and hope our font have that character.
		return GetGlyphOutlineW(hdc, uChar, uFormat, lpgm, cbBuffer, lpvBuffer, lpmat2);
	}

	HFONT origFont = (HFONT)GetCurrentObject(hdc, OBJ_FONT);
	LOGFONTW lf;
	GetObjectW(origFont, sizeof(lf), &lf);
	HFONT newFont = font_create_for_character(&lf, uChar);
	if (newFont) {
		origFont = (HFONT)SelectObject(hdc, newFont);
	}
	int ret = GetGlyphOutlineW(hdc, uChar, uFormat, lpgm, cbBuffer, lpvBuffer, lpmat2);
	if (newFont) {
		SelectObject(hdc, origFont);
		DeleteObject(newFont);
	}
	return ret;
}

extern "C" int nsml_mod_init()
{
	InitializeCriticalSection(&cs);
	return 0;
}

extern "C" void nsml_mod_detour(void)
{
	detour_chain("gdi32.dll", 0,
		"GetGlyphOutlineA", th105_GetGlyphOutlineU,
		NULL
		);
}

extern "C" void nsml_mod_exit()
{
	DeleteCriticalSection(&cs);
}
<commit_msg>thcrap_tasofro: th123: load spells.js from th105 as well<commit_after>/**
  * Touhou Community Reliant Automatic Patcher
  * Tasogare Frontier support plugin
  *
  * ----
  *
  * New Super Marisa Land support functions
  */

#include <thcrap.h>
#include "thcrap_tasofro.h"
#include "tfcs.h"
#include "bgm.h"
#include "cv0.h"
#include "nsml_images.h"
#include <set>

/// Detour chains
/// -------------
W32U8_DETOUR_CHAIN_DEF(GetGlyphOutline);
/// -------------

static CRITICAL_SECTION cs;
static std::set<const char*, bool(*)(const char*, const char*)> game_fallback_ignore_list([](const char *a, const char *b){ return strcmp(a, b) < 0; });

// Copy-paste of fn_for_game from patchfile.cpp
static char* fn_for_th105(const char *fn)
{
	const char *game_id = "th105";
	size_t game_id_len = strlen(game_id) + 1;
	char *full_fn;

	if (!fn) {
		return NULL;
	}
	full_fn = (char*)malloc(game_id_len + strlen(fn) + 1);

	full_fn[0] = 0; // Because strcat
	if (game_id) {
		strncpy(full_fn, game_id, game_id_len);
		strcat(full_fn, "/");
	}
	strcat(full_fn, fn);
	return full_fn;
}

json_t *th123_resolve_chain_game(const char *fn)
{
	json_t *ret = nullptr;

	// First, th105
	if (game_fallback_ignore_list.find(fn) == game_fallback_ignore_list.end()) {
		char *fn_game = fn_for_th105(fn);
		ret = resolve_chain(fn_game);
		SAFE_FREE(fn_game);
	}

	char *fn_common = fn_for_game(fn);
	const char *fn_common_ptr = fn_common ? fn_common : fn;
	json_t *th123_ret = resolve_chain(fn_common_ptr);
	if (ret && th123_ret) {
		json_array_extend(ret, th123_ret);
		json_decref(th123_ret);
	}
	else if (!ret && th123_ret) {
		ret = th123_ret;
	}
	SAFE_FREE(fn_common);
	return ret;
}

int nsml_init()
{
	if (game_id == TH_MEGAMARI) {
		patchhook_register("*.bmp", patch_bmp, get_bmp_size);
	}
	else if (game_id == TH_NSML) {
		// Increasing the file size makes the game crash.
		patchhook_register("*.cv2", patch_cv2, nullptr);
	}
	else if (game_id == TH105 || game_id == TH123) {
		patchhook_register("*.cv0", patch_cv0, nullptr);
		patchhook_register("*.cv1", patch_csv, nullptr);
		patchhook_register("*.cv2", patch_cv2, get_cv2_size);
		patchhook_register("*.dat", patch_dat_for_png, [](const char*, json_t*, size_t) -> size_t { return 0; });
	}

	if (game_id == TH105) {
		char *bgm_fn = fn_for_game("data/csv/system/music.cv1.jdiff");
		jsonvfs_add(bgm_fn, { "themes.js" }, bgm_generator);
		SAFE_FREE(bgm_fn);

		jsonvfs_game_add_map("data/csv/*/spellcard.cv1.jdiff", "spells.js");
		jsonvfs_game_add_map("data/csv/*/storyspell.cv1.jdiff", "spells.js");
	}
	else if (game_id == TH123) {
		set_resolve_chain_game(th123_resolve_chain_game);
		json_t *list = stack_game_json_resolve("game_fallback_ignore_list.js", nullptr);
		size_t i;
		json_t *value;
		json_array_foreach(list, i, value) {
			game_fallback_ignore_list.insert(json_string_value(value));
		}

		char *bgm_fn = fn_for_game("data/csv/system/music*.cv1.jdiff");
		jsonvfs_add_map(bgm_fn, "themes.js");
		SAFE_FREE(bgm_fn);

		char *pattern_spell = fn_for_game("data/csv/*/spellcard.cv1.jdiff");
		char *pattern_story = fn_for_game("data/csv/*/storyspell.cv1.jdiff");
		char *spells_th105 = fn_for_th105("spells.js");
		char *spells_th123 = fn_for_game("spells.js");
		jsonvfs_add_map(pattern_spell, spells_th105);
		jsonvfs_add_map(pattern_spell, spells_th123);
		jsonvfs_add_map(pattern_story, spells_th105);
		jsonvfs_add_map(pattern_story, spells_th123);
		SAFE_FREE(pattern_spell);
		SAFE_FREE(pattern_story);
		SAFE_FREE(spells_th105);
		SAFE_FREE(spells_th123);
	}
	return 0;
}

int BP_nsml_file_header(x86_reg_t *regs, json_t *bp_info)
{
	// Parameters
	// ----------
	const char *filename = (const char*)json_object_get_immediate(bp_info, regs, "file_name");
	size_t fn_size = json_object_get_immediate(bp_info, regs, "fn_size");
	// ----------

	char *uFilename;
	if (fn_size) {
		uFilename = EnsureUTF8(filename, fn_size);
	}
	else {
		uFilename = EnsureUTF8(filename, strlen(filename));
	}
	CharLowerA(uFilename);

	json_t *new_bp_info = json_copy(bp_info);
	json_object_set_new(new_bp_info, "file_name", json_integer((json_int_t)uFilename));
	EnterCriticalSection(&cs);
	int ret = BP_file_header(regs, new_bp_info);
	LeaveCriticalSection(&cs);

	json_decref(new_bp_info);
	free(uFilename);
	return ret;
}

static void megamari_patch(const file_rep_t *fr, BYTE *buffer, size_t size)
{
	BYTE key = ((fr->offset >> 1) | 8) & 0xFF;
	for (unsigned int i = 0; i < size; i++) {
		buffer[i] ^= key;
	}
}

static void nsml_patch(const file_rep_t *fr, BYTE *buffer, size_t size)
{
	BYTE key = ((fr->offset >> 1) | 0x23) & 0xFF;
	for (unsigned int i = 0; i < size; i++) {
		buffer[i] ^= key;
	}
}

static void th105_patch(const file_rep_t *fr, BYTE *buffer, size_t size)
{
	nsml_patch(fr, buffer, size);
	const char *ext = PathFindExtensionA(fr->name);
	if (!strcmp(ext, ".cv0") || !strcmp(ext, ".cv1")) {
		unsigned char xorval = 0x8b;
		unsigned char xoradd = 0x71;
		unsigned char xoraddadd = 0x95;
		for (unsigned int i = 0; i < size; i++) {
			buffer[i] ^= xorval;
			xorval += xoradd;
			xoradd += xoraddadd;
		}
	}
}

int BP_nsml_read_file(x86_reg_t *regs, json_t *bp_info)
{
	// Parameters
	// ----------
	const char *file_name = (const char*)json_object_get_immediate(bp_info, regs, "file_name");
	// ----------

	// bp_info may be used by several threads at the same time, so we can't change its values.
	json_t *new_bp_info = json_deep_copy(bp_info);
	char *uFilename = nullptr;

	if (file_name) {
		uFilename = EnsureUTF8(file_name, strlen(file_name));
		CharLowerA(uFilename);
		json_object_set_new(new_bp_info, "file_name", json_integer((json_int_t)uFilename));
	}

	if (game_id == TH_MEGAMARI) {
		json_object_set_new(new_bp_info, "post_read", json_integer((json_int_t)megamari_patch));
		json_object_set_new(new_bp_info, "post_patch", json_integer((json_int_t)megamari_patch));
	}
	else if (game_id == TH105 || game_id == TH123) {
		json_object_set_new(new_bp_info, "post_read", json_integer((json_int_t)th105_patch));
		json_object_set_new(new_bp_info, "post_patch", json_integer((json_int_t)th105_patch));
	}
	else {
		json_object_set_new(new_bp_info, "post_read", json_integer((json_int_t)nsml_patch));
		json_object_set_new(new_bp_info, "post_patch", json_integer((json_int_t)nsml_patch));
	}
	int ret = BP_fragmented_read_file(regs, new_bp_info);
	json_decref(new_bp_info);
	free(uFilename);
	return ret;
}

// In th105, relying on the last open file doesn't work. So we'll use the file object instead.
int BP_th105_file_new(x86_reg_t *regs, json_t *bp_info)
{
	// Parameters
	// ----------
	const char *file_name = (const char*)json_object_get_immediate(bp_info, regs, "file_name");
	void *file_object = (void*)json_object_get_immediate(bp_info, regs, "file_object");
	// ----------

	if (!file_name || !file_object) {
		return 1;
	}
	char *uFilename = EnsureUTF8(file_name, strlen(file_name));
	CharLowerA(uFilename);
	file_rep_t *fr = file_rep_get(uFilename);
	if (fr) {
		file_rep_set_object(fr, file_object);
	}
	free(uFilename);
	return 1;
}

int BP_th105_file_delete(x86_reg_t *regs, json_t *bp_info)
{
	// Parameters
	// ----------
	void *file_object = (void*)json_object_get_immediate(bp_info, regs, "file_object");
	// ----------

	if (!file_object) {
		return 1;
	}
	file_rep_t *fr = file_rep_get_by_object(file_object);
	if (fr) {
		file_rep_set_object(fr, nullptr);
	}
	return 1;
}

int BP_th105_font_spacing(x86_reg_t *regs, json_t *bp_info)
{
	// Parameters
	// ----------
	size_t font_size     = json_object_get_immediate(bp_info, regs, "font_size");
	size_t *y_offset     = json_object_get_pointer(bp_info, regs, "y_offset");
	size_t *font_spacing = json_object_get_pointer(bp_info, regs, "font_spacing");
	// ----------

	if (!font_size) {
		return 1;
	}

	json_t *entry = json_object_numkey_get(json_object_get(bp_info, "new_y_offset"), font_size);
	if (entry && json_is_integer(entry) && y_offset) {
		*y_offset  = (size_t)json_integer_value(entry);
	}

	entry = json_object_numkey_get(json_object_get(bp_info, "new_spacing"), font_size);
	if (entry && json_is_integer(entry) && font_spacing) {
		*font_spacing = (size_t)json_integer_value(entry);
	}
	return 1;
}

DWORD WINAPI th105_GetGlyphOutlineU(HDC hdc, UINT uChar, UINT uFormat, LPGLYPHMETRICS lpgm, DWORD cbBuffer, LPVOID lpvBuffer, const MAT2 *lpmat2)
{
	uChar = CharToUTF16(uChar);

	if (uChar & 0xFFFF0000 ||
		font_has_character(hdc, uChar)) {
		// is_character_in_font won't work if the character doesn't fit into a WCHAR.
		// When it happens, we'll be optimistic and hope our font have that character.
		return GetGlyphOutlineW(hdc, uChar, uFormat, lpgm, cbBuffer, lpvBuffer, lpmat2);
	}

	HFONT origFont = (HFONT)GetCurrentObject(hdc, OBJ_FONT);
	LOGFONTW lf;
	GetObjectW(origFont, sizeof(lf), &lf);
	HFONT newFont = font_create_for_character(&lf, uChar);
	if (newFont) {
		origFont = (HFONT)SelectObject(hdc, newFont);
	}
	int ret = GetGlyphOutlineW(hdc, uChar, uFormat, lpgm, cbBuffer, lpvBuffer, lpmat2);
	if (newFont) {
		SelectObject(hdc, origFont);
		DeleteObject(newFont);
	}
	return ret;
}

extern "C" int nsml_mod_init()
{
	InitializeCriticalSection(&cs);
	return 0;
}

extern "C" void nsml_mod_detour(void)
{
	detour_chain("gdi32.dll", 0,
		"GetGlyphOutlineA", th105_GetGlyphOutlineU,
		NULL
		);
}

extern "C" void nsml_mod_exit()
{
	DeleteCriticalSection(&cs);
}
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

// RUN: cat %s | %cling -Xclang -verify
// This test verifies that we get nice warning if a method on null ptr object is
// called.
// XFAIL:*
extern "C" int printf(const char* fmt, ...);
class MyClass {
private:
  int a;
public:
  MyClass() : a(1){}
  int getA(){return a;}
};
MyClass* my = 0;
my->getA() // expected-warning {{you are about to dereference null ptr, which probably will lead to seg violation. Do you want to proceed?[y/n]}}

struct AggregatedNull {
  MyClass* m;
  AggregatedNull() : m(0) {}
}

AggregatedNull agrNull;
agrNull.m->getA(); // expected-warning {{you are about to dereference null ptr, which probably will lead to seg violation. Do you want to proceed?[y/n]}}

.q
<commit_msg>Enable the NullDeref Cling test for MethodCalls.<commit_after>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

// RUN: cat %s | %cling -Xclang -verify
// This test verifies that we get nice warning if a method on null ptr object is
// called.

extern "C" int printf(const char* fmt, ...);
class MyClass {
private:
  int a;
public:
  MyClass() : a(1){}
  int getA(){return a;}
};
MyClass* my = 0;
my->getA() // expected-warning {{null passed to a callee that requires a non-null argument}}

struct AggregatedNull {
  MyClass* m;
  AggregatedNull() : m(0) {}
}

AggregatedNull agrNull;
agrNull.m->getA(); // expected-warning {{null passed to a callee that requires a non-null argument}}

.q
<|endoftext|>


<commit_before>#include "helpers/file_helpers.h"
#include <sys/stat.h>
#include <errno.h>
#include <fstream>

using std::string;
using std::ifstream;
using std::istreambuf_iterator;
using std::ofstream;
using std::vector;

bool file_exists(const string &path) {
  struct stat file_stat;
  return stat(path.c_str(), &file_stat) == 0;
}

int get_modified_time(const string &path) {
  struct stat file_stat;
  if (stat(path.c_str(), &file_stat) != 0) {
    if (errno != ENOENT)
      fprintf(stderr, "Error in stat() for path: %s\n", + path.c_str());
    return 0;
  }
  return file_stat.st_mtime;
}

string read_file(const string &path) {
  ifstream file(path);
  istreambuf_iterator<char> file_iterator(file), end_iterator;
  string content(file_iterator, end_iterator);
  file.close();
  return content;
}

void write_file(const string &path, const string &content) {
  ofstream file(path);
  file << content;
  file.close();
}

#ifdef _WIN32

#include <windows.h>

const char *path_separator = "\\";

vector<string> list_directory(const string &path) {
  vector<string> result;

  WIN32_FIND_DATA search_data;
  HANDLE handle = FindFirstFile((path + "\\*").c_str(), &search_data);
  while (handle != INVALID_HANDLE_VALUE) {
    string name(search_data.cFileName);
    result.push_back(name);
    if (FindNextFile(handle, &search_data) == FALSE) break;
  }

  return result;
}

#else

#include <dirent.h>

const char *path_separator = "/";

vector<string> list_directory(const string &path) {
  vector<string> result;

  DIR *dir = opendir(path.c_str());
  if (!dir) {
    printf("\nTest error - no such directory '%s'", path.c_str());
    return result;
  }

  struct dirent *dir_entry;
  while ((dir_entry = readdir(dir))) {
    string name(dir_entry->d_name);
    if (name != "." && name != "..") {
      result.push_back(name);
    }
  }

  closedir(dir);
  return result;
}

#endif

string join_path(const vector<string> &parts) {
  string result;
  for (const string &part : parts) {
    if (!result.empty()) result += path_separator;
    result += part;
  }
  return result;
}
<commit_msg>Read files in binary mode in tests<commit_after>#include "helpers/file_helpers.h"
#include <sys/stat.h>
#include <errno.h>
#include <fstream>

using std::string;
using std::ifstream;
using std::istreambuf_iterator;
using std::ofstream;
using std::vector;

bool file_exists(const string &path) {
  struct stat file_stat;
  return stat(path.c_str(), &file_stat) == 0;
}

int get_modified_time(const string &path) {
  struct stat file_stat;
  if (stat(path.c_str(), &file_stat) != 0) {
    if (errno != ENOENT)
      fprintf(stderr, "Error in stat() for path: %s\n", + path.c_str());
    return 0;
  }
  return file_stat.st_mtime;
}

string read_file(const string &path) {
  ifstream file(path, std::ios::binary);
  istreambuf_iterator<char> file_iterator(file), end_iterator;
  string content(file_iterator, end_iterator);
  file.close();
  return content;
}

void write_file(const string &path, const string &content) {
  ofstream file(path);
  file << content;
  file.close();
}

#ifdef _WIN32

#include <windows.h>

const char *path_separator = "\\";

vector<string> list_directory(const string &path) {
  vector<string> result;

  WIN32_FIND_DATA search_data;
  HANDLE handle = FindFirstFile((path + "\\*").c_str(), &search_data);
  while (handle != INVALID_HANDLE_VALUE) {
    string name(search_data.cFileName);
    result.push_back(name);
    if (FindNextFile(handle, &search_data) == FALSE) break;
  }

  return result;
}

#else

#include <dirent.h>

const char *path_separator = "/";

vector<string> list_directory(const string &path) {
  vector<string> result;

  DIR *dir = opendir(path.c_str());
  if (!dir) {
    printf("\nTest error - no such directory '%s'", path.c_str());
    return result;
  }

  struct dirent *dir_entry;
  while ((dir_entry = readdir(dir))) {
    string name(dir_entry->d_name);
    if (name != "." && name != "..") {
      result.push_back(name);
    }
  }

  closedir(dir);
  return result;
}

#endif

string join_path(const vector<string> &parts) {
  string result;
  for (const string &part : parts) {
    if (!result.empty()) result += path_separator;
    result += part;
  }
  return result;
}
<|endoftext|>


<commit_before>
#include <Hord/utility.hpp>
#include <Hord/IO/Prop.hpp>

#include <cassert>
#include <iostream>
#include <bitset>

using Hord::enum_cast;
using Type = Hord::IO::PropType;
using State = Hord::IO::PropState;
using Store = Hord::IO::PropStateStore;

void
print_store(
	Store const& s,
	Type const t = static_cast<Type>(0u)
) {
	bool const typed = 0u != enum_cast(t);
	unsigned const value
		= typed
		? enum_cast(s.get_state(t))
		: s.get_value()
	;

	if (typed) {
		std::cout
			<< Hord::IO::get_prop_type_name(t) << ": "
			<< std::bitset<4u>{value}
		;
	} else {
		std::cout
			<< "value: "
			<< std::bitset<4u>{value >> (4 << 2)} << ' '
			<< std::bitset<4u>{value >> (3 << 2)} << ' '
			<< std::bitset<4u>{value >> (2 << 2)} << ' '
			<< std::bitset<4u>{value >> (1 << 2)} << ' '
			<< std::bitset<4u>{value >> (0 << 2)} << ' '
		;
	}
	std::cout << '\n';
}

signed
main() {
	Store
		s_all{true, true},
		s_neither{false, false}
	;
	unsigned const
		value_init_all = s_all.get_value(),
		value_init_neither = s_neither.get_value()
	;

	std::cout << "s_all:\n";
	print_store(s_all);
	print_store(s_all, Type::primary);
	print_store(s_all, Type::auxiliary);

	std::cout << "\ns_neither:\n";
	print_store(s_neither);
	print_store(s_neither, Type::primary);
	print_store(s_neither, Type::auxiliary);

	std::cout << '\n';

	// Constructed state
	assert(s_all.all_uninitialized());
	assert(s_neither.all_uninitialized());

	assert(0u == value_init_neither);

	assert(s_all.has(Type::primary, State::original));
	assert(s_all.has(Type::auxiliary, State::original));

	assert(!s_neither.has(Type::primary, State::original));
	assert(!s_neither.has(Type::auxiliary, State::original));

	assert(s_all.is_supplied(Type::primary));
	assert(s_all.has_exact(Type::primary, State::not_supplied));
	assert(s_all.is_supplied(Type::auxiliary));
	assert(s_all.has_exact(Type::auxiliary, State::not_supplied));

	assert(!s_neither.is_supplied(Type::primary));
	assert(!s_neither.has_exact(Type::primary, State::not_supplied));
	assert(!s_neither.is_supplied(Type::auxiliary));
	assert(!s_neither.has_exact(Type::auxiliary, State::not_supplied));

	// Unchanged when resetting while all_uninitialized()
	s_all.reset_all();
	assert(s_all.get_value() == value_init_all);

	// not_supplied are unassignable
	s_all.reset(Type::primary);
	s_all.assign(Type::auxiliary, State::modified);
	assert(s_all.get_value() == value_init_all);

	// Assignments
	s_all.assign(Type::identity, State::original);
	s_all.assign(Type::metadata, State::original);
	s_all.assign(Type::scratch, State::original);

	print_store(s_all);

	assert(s_all.all_original());
	assert(!s_all.any_modified());

	// Back to initial value when resetting
	s_all.reset_all();
	assert(s_all.get_value() == value_init_all);

	// More assignments
	s_all.assign(Type::identity, State::modified);
	s_all.assign(Type::metadata, State::modified);
	s_all.assign(Type::scratch, State::modified);

	print_store(s_all);

	assert(!s_all.all_original());
	assert(s_all.any_modified());

	return 0;
}
<commit_msg>test/io/prop_state_store: added more init case assertions.<commit_after>
#include <Hord/utility.hpp>
#include <Hord/IO/Prop.hpp>

#include <cassert>
#include <iostream>
#include <bitset>

using Hord::enum_cast;
using Type = Hord::IO::PropType;
using State = Hord::IO::PropState;
using Store = Hord::IO::PropStateStore;

void
print_store(
	Store const& s,
	Type const t = static_cast<Type>(0u)
) {
	bool const typed = 0u != enum_cast(t);
	unsigned const value
		= typed
		? enum_cast(s.get_state(t))
		: s.get_value()
	;

	if (typed) {
		std::cout
			<< Hord::IO::get_prop_type_name(t) << ": "
			<< std::bitset<4u>{value}
		;
	} else {
		std::cout
			<< "value: "
			<< std::bitset<4u>{value >> (4 << 2)} << ' '
			<< std::bitset<4u>{value >> (3 << 2)} << ' '
			<< std::bitset<4u>{value >> (2 << 2)} << ' '
			<< std::bitset<4u>{value >> (1 << 2)} << ' '
			<< std::bitset<4u>{value >> (0 << 2)} << ' '
		;
	}
	std::cout << '\n';
}

signed
main() {
	Store
		s_all{true, true},
		s_neither{false, false}
	;
	unsigned const
		value_init_all = s_all.get_value(),
		value_init_neither = s_neither.get_value()
	;

	std::cout << "s_all:\n";
	print_store(s_all);
	print_store(s_all, Type::primary);
	print_store(s_all, Type::auxiliary);

	std::cout << "\ns_neither:\n";
	print_store(s_neither);
	print_store(s_neither, Type::primary);
	print_store(s_neither, Type::auxiliary);

	std::cout << '\n';

	// Constructed state
	assert(s_all.all_uninitialized());
	assert(s_neither.all_uninitialized());

	assert(0u == value_init_neither);

	assert(!s_all.all_original());
	assert(!s_all.any_modified());

	assert(s_all.has(Type::primary, State::original));
	assert(s_all.has(Type::auxiliary, State::original));

	assert(!s_neither.has(Type::primary, State::original));
	assert(!s_neither.has(Type::auxiliary, State::original));

	assert(s_all.is_supplied(Type::primary));
	assert(s_all.has_exact(Type::primary, State::not_supplied));
	assert(s_all.is_supplied(Type::auxiliary));
	assert(s_all.has_exact(Type::auxiliary, State::not_supplied));

	assert(!s_neither.is_supplied(Type::primary));
	assert(!s_neither.has_exact(Type::primary, State::not_supplied));
	assert(!s_neither.is_supplied(Type::auxiliary));
	assert(!s_neither.has_exact(Type::auxiliary, State::not_supplied));

	// Unchanged when resetting while all_uninitialized()
	s_all.reset_all();
	assert(s_all.get_value() == value_init_all);

	// not_supplied are unassignable
	s_all.reset(Type::primary);
	s_all.assign(Type::auxiliary, State::modified);
	assert(s_all.get_value() == value_init_all);

	// Assignments
	s_all.assign(Type::identity, State::original);
	s_all.assign(Type::metadata, State::original);
	s_all.assign(Type::scratch, State::original);

	print_store(s_all);

	assert(s_all.all_original());
	assert(!s_all.any_modified());

	// Back to initial value when resetting
	s_all.reset_all();
	assert(s_all.get_value() == value_init_all);

	// More assignments
	s_all.assign(Type::identity, State::modified);
	s_all.assign(Type::metadata, State::modified);
	s_all.assign(Type::scratch, State::modified);

	print_store(s_all);

	assert(!s_all.all_original());
	assert(s_all.any_modified());

	return 0;
}
<|endoftext|>


<commit_before>/*
    This file is part of solidity.

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

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

    You should have received a copy of the GNU General Public License
    along with solidity.  If not, see <http://www.gnu.org/licenses/>.
*/
/**
 * @author Alex Beregszaszi
 * @date 2016
 * End to end tests for LLL.
 */

#include <string>
#include <memory>
#include <boost/test/unit_test.hpp>
#include <test/liblll/ExecutionFramework.h>

using namespace std;

namespace dev
{
namespace lll
{
namespace test
{

BOOST_FIXTURE_TEST_SUITE(LLLEndToEndTest, LLLExecutionFramework)

BOOST_AUTO_TEST_CASE(smoke_test)
{
        char const* sourceCode = "(returnlll { (return \"test\") })";
        compileAndRun(sourceCode);
        BOOST_CHECK(callFallback() == encodeArgs(string("test", 4)));
}

BOOST_AUTO_TEST_CASE(bare_panic)
{
	char const* sourceCode = "(panic)";
	compileAndRunWithoutCheck(sourceCode);
	BOOST_REQUIRE(m_output.empty());
}

BOOST_AUTO_TEST_CASE(panic)
{
	char const* sourceCode = "{ (panic) }";
	compileAndRunWithoutCheck(sourceCode);
	BOOST_REQUIRE(m_output.empty());
}

BOOST_AUTO_TEST_CASE(exp_operator_const)
{
	char const* sourceCode = R"(
		(returnlll
			(return (exp 2 3)))
	)";
	compileAndRun(sourceCode);
	BOOST_CHECK(callFallback() == toBigEndian(u256(8)));
}

BOOST_AUTO_TEST_CASE(exp_operator_const_signed)
{
	char const* sourceCode = R"(
		(returnlll
			(return (exp (- 0 2) 3)))
	)";
	compileAndRun(sourceCode);
	BOOST_CHECK(callFallback() == toBigEndian(u256(-8)));
}

BOOST_AUTO_TEST_CASE(exp_operator_on_range)
{
	char const* sourceCode = R"(
		(returnlll
			(seq
				(when (= (div (calldataload 0x00) (exp 2 224)) 0xb3de648b)
					(return (exp 2 (calldataload 0x04))))
				(jump 0x02)))
	)";
	compileAndRun(sourceCode);
	testContractAgainstCppOnRange("f(uint256)", [](u256 const& a) -> u256 { return u256(1 << a.convert_to<int>()); }, 0, 16);
}

BOOST_AUTO_TEST_CASE(constructor_argument_internal_numeric)
{
	char const* sourceCode = R"(
		(seq
			(sstore 0x00 65535)
			(returnlll
				(return @@0x00)))
	)";
	compileAndRun(sourceCode);
	BOOST_CHECK(callFallback() == encodeArgs(u256(65535)));
}

BOOST_AUTO_TEST_CASE(constructor_argument_internal_string)
{
	char const* sourceCode = R"(
		(seq
			(sstore 0x00 "test")
			(returnlll
				(return @@0x00)))
	)";
	compileAndRun(sourceCode);
	BOOST_CHECK(callFallback() == encodeArgs("test"));
}

BOOST_AUTO_TEST_CASE(constructor_arguments_external)
{
	char const* sourceCode = R"(
		(seq
			(codecopy 0x00 (bytecodesize) 64)
			(sstore 0x00 @0x00)
			(sstore 0x01 @0x20)
			(returnlll
				(seq
					(when (= (div (calldataload 0x00) (exp 2 224)) 0xf2c9ecd8)
						(return @@0x00))
					(when (= (div (calldataload 0x00) (exp 2 224)) 0x89ea642f)
						(return @@0x01)))))
	)";
	compileAndRun(sourceCode, 0, "", encodeArgs(u256(65535), "test"));
	BOOST_CHECK(callContractFunction("getNumber()") == encodeArgs(u256(65535)));
	BOOST_CHECK(callContractFunction("getString()") == encodeArgs("test"));
}

BOOST_AUTO_TEST_CASE(fallback_and_invalid_function)
{
	char const* sourceCode = R"(
		(returnlll
			(seq
				(when (= (div (calldataload 0x00) (exp 2 224)) 0xab5ed150)
					(return "one"))
				(when (= (div (calldataload 0x00) (exp 2 224)) 0xee784123)
					(return "two"))
				(return "three")))
	)";
	compileAndRun(sourceCode);
	BOOST_CHECK(callContractFunction("getOne()") == encodeArgs("one"));
	BOOST_CHECK(callContractFunction("getTwo()") == encodeArgs("two"));
	BOOST_CHECK(callContractFunction("invalidFunction()") == encodeArgs("three"));
	BOOST_CHECK(callFallback() == encodeArgs("three"));
}

BOOST_AUTO_TEST_CASE(lit_string)
{
	char const* sourceCode = R"(
		(returnlll
			(seq
				(lit 0x00 "abcdef")
				(return 0x00 0x20)))
	)";
	compileAndRun(sourceCode);
	BOOST_CHECK(callFallback() == encodeArgs(string("abcdef")));
}

BOOST_AUTO_TEST_CASE(arithmetic)
{
	char const* sourceCode = R"(
		(returnlll
			(seq
				(mstore8 0x00 (+ 160 22))
				(mstore8 0x01 (- 223 41))
				(mstore8 0x02 (* 33 2))
				(mstore8 0x03 (/ 10 2))
				(mstore8 0x04 (% 67 2))
				(mstore8 0x05 (& 15 8))
				(mstore8 0x06 (| 18 8))
				(mstore8 0x07 (^ 26 6))
				(return 0x00 0x20)))
	)";
	compileAndRun(sourceCode);
	BOOST_CHECK(callFallback() == encodeArgs(
		fromHex("b6b6420501081a1c000000000000000000000000000000000000000000000000")));
}

BOOST_AUTO_TEST_CASE(binary)
{
	char const* sourceCode = R"(
		(returnlll
			(seq
				(mstore8 0x00 (< 53 87))
				(mstore8 0x01 (< 73 42))
				(mstore8 0x02 (<= 37 94))
				(mstore8 0x03 (<= 37 37))
				(mstore8 0x04 (<= 183 34))
				(mstore8 0x05 (S< (- 0 53) 87))
				(mstore8 0x06 (S< 73 (- 0 42)))
				(mstore8 0x07 (S<= (- 0 37) 94))
				(mstore8 0x08 (S<= (- 0 37) (- 0 37)))
				(mstore8 0x09 (S<= 183 (- 0 34)))
				(mstore8 0x0a (> 73 42))
				(mstore8 0x0b (> 53 87))
				(mstore8 0x0c (>= 94 37))
				(mstore8 0x0d (>= 94 94))
				(mstore8 0x0e (>= 34 183))
				(mstore8 0x0f (S> 73 (- 0 42)))
				(mstore8 0x10 (S> (- 0 53) 87))
				(mstore8 0x11 (S>= 94 (- 0 37)))
				(mstore8 0x12 (S>= (- 0 94) (- 0 94)))
				(mstore8 0x13 (S>= (- 0 34) 183))
				(mstore8 0x14 (= 53 53))
				(mstore8 0x15 (= 73 42))
				(mstore8 0x16 (!= 37 94))
				(mstore8 0x17 (!= 37 37))
				(return 0x00 0x20)))
	)";
	compileAndRun(sourceCode);
	BOOST_CHECK(callFallback() == encodeArgs(
		fromHex("0100010100010001010001000101000100010100010001000000000000000000")));
}

BOOST_AUTO_TEST_CASE(unary)
{
	char const* sourceCode = R"(
		(returnlll
			(seq
				(mstore8 0x00 (! (< 53 87)))
				(mstore8 0x01 (! (>= 42 73)))
				(mstore8 0x02 (~ 0x7f))
				(mstore8 0x03 (~ 0xaa))
				(return 0x00 0x20)))
	)";
	compileAndRun(sourceCode);
	BOOST_CHECK(callFallback() == encodeArgs(
		fromHex("0001805500000000000000000000000000000000000000000000000000000000")));
}

BOOST_AUTO_TEST_CASE(assembly_mload_mstore)
{
	char const* sourceCode = R"(
		(returnlll
			(asm
				0x07 0x00 mstore
				"abcdef" 0x20 mstore
				0x00 mload 0x40 mstore
				0x20 mload 0x60 mstore
				0x40 0x40 return))
	)";
	compileAndRun(sourceCode);
	BOOST_CHECK(callFallback() == encodeArgs(u256(7), string("abcdef")));
}

BOOST_AUTO_TEST_CASE(assembly_sload_sstore)
{
	char const* sourceCode = R"(
		(returnlll
			(asm
				0x07 0x00 sstore
				"abcdef" 0x01 sstore
				0x00 sload 0x00 mstore
				0x01 sload 0x20 mstore
				0x40 0x00 return))
	)";
	compileAndRun(sourceCode);
	BOOST_CHECK(callFallback() == encodeArgs(u256(7), string("abcdef")));
}

BOOST_AUTO_TEST_CASE(assembly_codecopy)
{
	char const* sourceCode = R"(
		(returnlll
			(seq
				(lit 0x00 "abcdef")
				(asm
					0x06 0x16 0x20 codecopy
					0x20 0x20 return)))
	)";
	compileAndRun(sourceCode);
	BOOST_CHECK(callFallback() == encodeArgs(string("abcdef")));
}

BOOST_AUTO_TEST_SUITE_END()

}
}
} // end namespaces
<commit_msg>Add an end-to-end test about LLL macro with zero arguments<commit_after>/*
    This file is part of solidity.

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

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

    You should have received a copy of the GNU General Public License
    along with solidity.  If not, see <http://www.gnu.org/licenses/>.
*/
/**
 * @author Alex Beregszaszi
 * @date 2016
 * End to end tests for LLL.
 */

#include <string>
#include <memory>
#include <boost/test/unit_test.hpp>
#include <test/liblll/ExecutionFramework.h>

using namespace std;

namespace dev
{
namespace lll
{
namespace test
{

BOOST_FIXTURE_TEST_SUITE(LLLEndToEndTest, LLLExecutionFramework)

BOOST_AUTO_TEST_CASE(smoke_test)
{
        char const* sourceCode = "(returnlll { (return \"test\") })";
        compileAndRun(sourceCode);
        BOOST_CHECK(callFallback() == encodeArgs(string("test", 4)));
}

BOOST_AUTO_TEST_CASE(bare_panic)
{
	char const* sourceCode = "(panic)";
	compileAndRunWithoutCheck(sourceCode);
	BOOST_REQUIRE(m_output.empty());
}

BOOST_AUTO_TEST_CASE(panic)
{
	char const* sourceCode = "{ (panic) }";
	compileAndRunWithoutCheck(sourceCode);
	BOOST_REQUIRE(m_output.empty());
}

BOOST_AUTO_TEST_CASE(exp_operator_const)
{
	char const* sourceCode = R"(
		(returnlll
			(return (exp 2 3)))
	)";
	compileAndRun(sourceCode);
	BOOST_CHECK(callFallback() == toBigEndian(u256(8)));
}

BOOST_AUTO_TEST_CASE(exp_operator_const_signed)
{
	char const* sourceCode = R"(
		(returnlll
			(return (exp (- 0 2) 3)))
	)";
	compileAndRun(sourceCode);
	BOOST_CHECK(callFallback() == toBigEndian(u256(-8)));
}

BOOST_AUTO_TEST_CASE(exp_operator_on_range)
{
	char const* sourceCode = R"(
		(returnlll
			(seq
				(when (= (div (calldataload 0x00) (exp 2 224)) 0xb3de648b)
					(return (exp 2 (calldataload 0x04))))
				(jump 0x02)))
	)";
	compileAndRun(sourceCode);
	testContractAgainstCppOnRange("f(uint256)", [](u256 const& a) -> u256 { return u256(1 << a.convert_to<int>()); }, 0, 16);
}

BOOST_AUTO_TEST_CASE(constructor_argument_internal_numeric)
{
	char const* sourceCode = R"(
		(seq
			(sstore 0x00 65535)
			(returnlll
				(return @@0x00)))
	)";
	compileAndRun(sourceCode);
	BOOST_CHECK(callFallback() == encodeArgs(u256(65535)));
}

BOOST_AUTO_TEST_CASE(constructor_argument_internal_string)
{
	char const* sourceCode = R"(
		(seq
			(sstore 0x00 "test")
			(returnlll
				(return @@0x00)))
	)";
	compileAndRun(sourceCode);
	BOOST_CHECK(callFallback() == encodeArgs("test"));
}

BOOST_AUTO_TEST_CASE(constructor_arguments_external)
{
	char const* sourceCode = R"(
		(seq
			(codecopy 0x00 (bytecodesize) 64)
			(sstore 0x00 @0x00)
			(sstore 0x01 @0x20)
			(returnlll
				(seq
					(when (= (div (calldataload 0x00) (exp 2 224)) 0xf2c9ecd8)
						(return @@0x00))
					(when (= (div (calldataload 0x00) (exp 2 224)) 0x89ea642f)
						(return @@0x01)))))
	)";
	compileAndRun(sourceCode, 0, "", encodeArgs(u256(65535), "test"));
	BOOST_CHECK(callContractFunction("getNumber()") == encodeArgs(u256(65535)));
	BOOST_CHECK(callContractFunction("getString()") == encodeArgs("test"));
}

BOOST_AUTO_TEST_CASE(fallback_and_invalid_function)
{
	char const* sourceCode = R"(
		(returnlll
			(seq
				(when (= (div (calldataload 0x00) (exp 2 224)) 0xab5ed150)
					(return "one"))
				(when (= (div (calldataload 0x00) (exp 2 224)) 0xee784123)
					(return "two"))
				(return "three")))
	)";
	compileAndRun(sourceCode);
	BOOST_CHECK(callContractFunction("getOne()") == encodeArgs("one"));
	BOOST_CHECK(callContractFunction("getTwo()") == encodeArgs("two"));
	BOOST_CHECK(callContractFunction("invalidFunction()") == encodeArgs("three"));
	BOOST_CHECK(callFallback() == encodeArgs("three"));
}

BOOST_AUTO_TEST_CASE(lit_string)
{
	char const* sourceCode = R"(
		(returnlll
			(seq
				(lit 0x00 "abcdef")
				(return 0x00 0x20)))
	)";
	compileAndRun(sourceCode);
	BOOST_CHECK(callFallback() == encodeArgs(string("abcdef")));
}

BOOST_AUTO_TEST_CASE(arithmetic)
{
	char const* sourceCode = R"(
		(returnlll
			(seq
				(mstore8 0x00 (+ 160 22))
				(mstore8 0x01 (- 223 41))
				(mstore8 0x02 (* 33 2))
				(mstore8 0x03 (/ 10 2))
				(mstore8 0x04 (% 67 2))
				(mstore8 0x05 (& 15 8))
				(mstore8 0x06 (| 18 8))
				(mstore8 0x07 (^ 26 6))
				(return 0x00 0x20)))
	)";
	compileAndRun(sourceCode);
	BOOST_CHECK(callFallback() == encodeArgs(
		fromHex("b6b6420501081a1c000000000000000000000000000000000000000000000000")));
}

BOOST_AUTO_TEST_CASE(binary)
{
	char const* sourceCode = R"(
		(returnlll
			(seq
				(mstore8 0x00 (< 53 87))
				(mstore8 0x01 (< 73 42))
				(mstore8 0x02 (<= 37 94))
				(mstore8 0x03 (<= 37 37))
				(mstore8 0x04 (<= 183 34))
				(mstore8 0x05 (S< (- 0 53) 87))
				(mstore8 0x06 (S< 73 (- 0 42)))
				(mstore8 0x07 (S<= (- 0 37) 94))
				(mstore8 0x08 (S<= (- 0 37) (- 0 37)))
				(mstore8 0x09 (S<= 183 (- 0 34)))
				(mstore8 0x0a (> 73 42))
				(mstore8 0x0b (> 53 87))
				(mstore8 0x0c (>= 94 37))
				(mstore8 0x0d (>= 94 94))
				(mstore8 0x0e (>= 34 183))
				(mstore8 0x0f (S> 73 (- 0 42)))
				(mstore8 0x10 (S> (- 0 53) 87))
				(mstore8 0x11 (S>= 94 (- 0 37)))
				(mstore8 0x12 (S>= (- 0 94) (- 0 94)))
				(mstore8 0x13 (S>= (- 0 34) 183))
				(mstore8 0x14 (= 53 53))
				(mstore8 0x15 (= 73 42))
				(mstore8 0x16 (!= 37 94))
				(mstore8 0x17 (!= 37 37))
				(return 0x00 0x20)))
	)";
	compileAndRun(sourceCode);
	BOOST_CHECK(callFallback() == encodeArgs(
		fromHex("0100010100010001010001000101000100010100010001000000000000000000")));
}

BOOST_AUTO_TEST_CASE(unary)
{
	char const* sourceCode = R"(
		(returnlll
			(seq
				(mstore8 0x00 (! (< 53 87)))
				(mstore8 0x01 (! (>= 42 73)))
				(mstore8 0x02 (~ 0x7f))
				(mstore8 0x03 (~ 0xaa))
				(return 0x00 0x20)))
	)";
	compileAndRun(sourceCode);
	BOOST_CHECK(callFallback() == encodeArgs(
		fromHex("0001805500000000000000000000000000000000000000000000000000000000")));
}

BOOST_AUTO_TEST_CASE(assembly_mload_mstore)
{
	char const* sourceCode = R"(
		(returnlll
			(asm
				0x07 0x00 mstore
				"abcdef" 0x20 mstore
				0x00 mload 0x40 mstore
				0x20 mload 0x60 mstore
				0x40 0x40 return))
	)";
	compileAndRun(sourceCode);
	BOOST_CHECK(callFallback() == encodeArgs(u256(7), string("abcdef")));
}

BOOST_AUTO_TEST_CASE(assembly_sload_sstore)
{
	char const* sourceCode = R"(
		(returnlll
			(asm
				0x07 0x00 sstore
				"abcdef" 0x01 sstore
				0x00 sload 0x00 mstore
				0x01 sload 0x20 mstore
				0x40 0x00 return))
	)";
	compileAndRun(sourceCode);
	BOOST_CHECK(callFallback() == encodeArgs(u256(7), string("abcdef")));
}

BOOST_AUTO_TEST_CASE(assembly_codecopy)
{
	char const* sourceCode = R"(
		(returnlll
			(seq
				(lit 0x00 "abcdef")
				(asm
					0x06 0x16 0x20 codecopy
					0x20 0x20 return)))
	)";
	compileAndRun(sourceCode);
	BOOST_CHECK(callFallback() == encodeArgs(string("abcdef")));
}

BOOST_AUTO_TEST_CASE(zeroarg_macro)
{
	char const* sourceCode = R"(
		(returnlll
			(seq
				(def 'zeroarg () (asm INVALID))
				(zeroarg)))
	)";
	compileAndRun(sourceCode);
	BOOST_CHECK(callFallback() == encodeArgs());
}

BOOST_AUTO_TEST_SUITE_END()

}
}
} // end namespaces
<|endoftext|>


<commit_before>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "main.h"

using namespace std;
template<typename MatrixType> void permutationmatrices(const MatrixType& m)
{
  typedef typename MatrixType::Index Index;
  typedef typename MatrixType::Scalar Scalar;
  enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime,
         Options = MatrixType::Options };
  typedef PermutationMatrix<Rows> LeftPermutationType;
  typedef Matrix<int, Rows, 1> LeftPermutationVectorType;
  typedef Map<LeftPermutationType> MapLeftPerm;
  typedef PermutationMatrix<Cols> RightPermutationType;
  typedef Matrix<int, Cols, 1> RightPermutationVectorType;
  typedef Map<RightPermutationType> MapRightPerm;

  Index rows = m.rows();
  Index cols = m.cols();

  MatrixType m_original = MatrixType::Random(rows,cols);
  LeftPermutationVectorType lv;
  randomPermutationVector(lv, rows);
  LeftPermutationType lp(lv);
  RightPermutationVectorType rv;
  randomPermutationVector(rv, cols);
  RightPermutationType rp(rv);
  MatrixType m_permuted = lp * m_original * rp;

  for (int i=0; i<rows; i++)
    for (int j=0; j<cols; j++)
        VERIFY_IS_APPROX(m_permuted(lv(i),j), m_original(i,rv(j)));

  Matrix<Scalar,Rows,Rows> lm(lp);
  Matrix<Scalar,Cols,Cols> rm(rp);

  VERIFY_IS_APPROX(m_permuted, lm*m_original*rm);

  VERIFY_IS_APPROX(lp.inverse()*m_permuted*rp.inverse(), m_original);
  VERIFY_IS_APPROX(lv.asPermutation().inverse()*m_permuted*rv.asPermutation().inverse(), m_original);
  VERIFY_IS_APPROX(MapLeftPerm(lv.data(),lv.size()).inverse()*m_permuted*MapRightPerm(rv.data(),rv.size()).inverse(), m_original);

  VERIFY((lp*lp.inverse()).toDenseMatrix().isIdentity());
  VERIFY((lv.asPermutation()*lv.asPermutation().inverse()).toDenseMatrix().isIdentity());
  VERIFY((MapLeftPerm(lv.data(),lv.size())*MapLeftPerm(lv.data(),lv.size()).inverse()).toDenseMatrix().isIdentity());

  LeftPermutationVectorType lv2;
  randomPermutationVector(lv2, rows);
  LeftPermutationType lp2(lv2);
  Matrix<Scalar,Rows,Rows> lm2(lp2);
  VERIFY_IS_APPROX((lp*lp2).toDenseMatrix().template cast<Scalar>(), lm*lm2);
  VERIFY_IS_APPROX((lv.asPermutation()*lv2.asPermutation()).toDenseMatrix().template cast<Scalar>(), lm*lm2);
  VERIFY_IS_APPROX((MapLeftPerm(lv.data(),lv.size())*MapLeftPerm(lv2.data(),lv2.size())).toDenseMatrix().template cast<Scalar>(), lm*lm2);

  LeftPermutationType identityp;
  identityp.setIdentity(rows);
  VERIFY_IS_APPROX(m_original, identityp*m_original);

  // check inplace permutations
  m_permuted = m_original;
  m_permuted = lp.inverse() * m_permuted;
  VERIFY_IS_APPROX(m_permuted, lp.inverse()*m_original);

  m_permuted = m_original;
  m_permuted = m_permuted * rp.inverse();
  VERIFY_IS_APPROX(m_permuted, m_original*rp.inverse());

  m_permuted = m_original;
  m_permuted = lp * m_permuted;
  VERIFY_IS_APPROX(m_permuted, lp*m_original);

  m_permuted = m_original;
  m_permuted = m_permuted * rp;
  VERIFY_IS_APPROX(m_permuted, m_original*rp);

  if(rows>1 && cols>1)
  {
    lp2 = lp;
    Index i = internal::random<Index>(0, rows-1);
    Index j;
    do j = internal::random<Index>(0, rows-1); while(j==i);
    lp2.applyTranspositionOnTheLeft(i, j);
    lm = lp;
    lm.row(i).swap(lm.row(j));
    VERIFY_IS_APPROX(lm, lp2.toDenseMatrix().template cast<Scalar>());

    RightPermutationType rp2 = rp;
    i = internal::random<Index>(0, cols-1);
    do j = internal::random<Index>(0, cols-1); while(j==i);
    rp2.applyTranspositionOnTheRight(i, j);
    rm = rp;
    rm.col(i).swap(rm.col(j));
    VERIFY_IS_APPROX(rm, rp2.toDenseMatrix().template cast<Scalar>());
  }
}

template<typename T>
void bug890()
{
  typedef Matrix<T, Dynamic, Dynamic> MatrixType;
  typedef Matrix<T, Dynamic, 1> VectorType;
  typedef Stride<Dynamic,Dynamic> S;
  typedef Map<MatrixType, Aligned, S> MapType;
  typedef PermutationMatrix<Dynamic> Perm;

  VectorType v1(2), v2(2), op(4), rhs(2);
  v1 << 666,667;
  op << 1,0,0,1;
  rhs << 42,42;

  Perm P(2);
  P.indices() << 1, 0;

  MapType(v1.data(),2,1,S(1,1)) = P * MapType(rhs.data(),2,1,S(1,1));
  VERIFY_IS_APPROX(v1, (P * rhs).eval());

  MapType(v1.data(),2,1,S(1,1)) = P.inverse() * MapType(rhs.data(),2,1,S(1,1));
  VERIFY_IS_APPROX(v1, (P.inverse() * rhs).eval());
}

void test_permutationmatrices()
{
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1( permutationmatrices(Matrix<float, 1, 1>()) );
    CALL_SUBTEST_2( permutationmatrices(Matrix3f()) );
    CALL_SUBTEST_3( permutationmatrices(Matrix<double,3,3,RowMajor>()) );
    CALL_SUBTEST_4( permutationmatrices(Matrix4d()) );
    CALL_SUBTEST_5( permutationmatrices(Matrix<double,40,60>()) );
    CALL_SUBTEST_6( permutationmatrices(Matrix<double,Dynamic,Dynamic,RowMajor>(20, 30)) );
    CALL_SUBTEST_7( permutationmatrices(MatrixXcf(15, 10)) );
  }
  CALL_SUBTEST_5( bug890<double>() );
}
<commit_msg>Check number of temporaries when applying permutations<commit_after>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#define TEST_ENABLE_TEMPORARY_TRACKING

#include "main.h"

using namespace std;
template<typename MatrixType> void permutationmatrices(const MatrixType& m)
{
  typedef typename MatrixType::Index Index;
  typedef typename MatrixType::Scalar Scalar;
  enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime,
         Options = MatrixType::Options };
  typedef PermutationMatrix<Rows> LeftPermutationType;
  typedef Matrix<int, Rows, 1> LeftPermutationVectorType;
  typedef Map<LeftPermutationType> MapLeftPerm;
  typedef PermutationMatrix<Cols> RightPermutationType;
  typedef Matrix<int, Cols, 1> RightPermutationVectorType;
  typedef Map<RightPermutationType> MapRightPerm;

  Index rows = m.rows();
  Index cols = m.cols();

  MatrixType m_original = MatrixType::Random(rows,cols);
  LeftPermutationVectorType lv;
  randomPermutationVector(lv, rows);
  LeftPermutationType lp(lv);
  RightPermutationVectorType rv;
  randomPermutationVector(rv, cols);
  RightPermutationType rp(rv);
  MatrixType m_permuted = MatrixType::Random(rows,cols);

  const int one_if_dynamic = MatrixType::SizeAtCompileTime==Dynamic ? 1 : 0;
  VERIFY_EVALUATION_COUNT(m_permuted = lp * m_original * rp, one_if_dynamic); // 1 temp for sub expression "lp * m_original"

  for (int i=0; i<rows; i++)
    for (int j=0; j<cols; j++)
        VERIFY_IS_APPROX(m_permuted(lv(i),j), m_original(i,rv(j)));

  Matrix<Scalar,Rows,Rows> lm(lp);
  Matrix<Scalar,Cols,Cols> rm(rp);

  VERIFY_IS_APPROX(m_permuted, lm*m_original*rm);

  m_permuted = m_original;
  VERIFY_EVALUATION_COUNT(m_permuted = lp * m_permuted * rp, one_if_dynamic);
  VERIFY_IS_APPROX(m_permuted, lm*m_original*rm);

  VERIFY_IS_APPROX(lp.inverse()*m_permuted*rp.inverse(), m_original);
  VERIFY_IS_APPROX(lv.asPermutation().inverse()*m_permuted*rv.asPermutation().inverse(), m_original);
  VERIFY_IS_APPROX(MapLeftPerm(lv.data(),lv.size()).inverse()*m_permuted*MapRightPerm(rv.data(),rv.size()).inverse(), m_original);

  VERIFY((lp*lp.inverse()).toDenseMatrix().isIdentity());
  VERIFY((lv.asPermutation()*lv.asPermutation().inverse()).toDenseMatrix().isIdentity());
  VERIFY((MapLeftPerm(lv.data(),lv.size())*MapLeftPerm(lv.data(),lv.size()).inverse()).toDenseMatrix().isIdentity());

  LeftPermutationVectorType lv2;
  randomPermutationVector(lv2, rows);
  LeftPermutationType lp2(lv2);
  Matrix<Scalar,Rows,Rows> lm2(lp2);
  VERIFY_IS_APPROX((lp*lp2).toDenseMatrix().template cast<Scalar>(), lm*lm2);
  VERIFY_IS_APPROX((lv.asPermutation()*lv2.asPermutation()).toDenseMatrix().template cast<Scalar>(), lm*lm2);
  VERIFY_IS_APPROX((MapLeftPerm(lv.data(),lv.size())*MapLeftPerm(lv2.data(),lv2.size())).toDenseMatrix().template cast<Scalar>(), lm*lm2);

  LeftPermutationType identityp;
  identityp.setIdentity(rows);
  VERIFY_IS_APPROX(m_original, identityp*m_original);

  // check inplace permutations
  m_permuted = m_original;
  VERIFY_EVALUATION_COUNT(m_permuted.noalias()= lp.inverse() * m_permuted, one_if_dynamic); // 1 temp to allocate the mask
  VERIFY_IS_APPROX(m_permuted, lp.inverse()*m_original);

  m_permuted = m_original;
  VERIFY_EVALUATION_COUNT(m_permuted.noalias() = m_permuted * rp.inverse(), one_if_dynamic); // 1 temp to allocate the mask
  VERIFY_IS_APPROX(m_permuted, m_original*rp.inverse());

  m_permuted = m_original;
  VERIFY_EVALUATION_COUNT(m_permuted.noalias() = lp * m_permuted, one_if_dynamic); // 1 temp to allocate the mask
  VERIFY_IS_APPROX(m_permuted, lp*m_original);

  m_permuted = m_original;
  VERIFY_EVALUATION_COUNT(m_permuted.noalias() = m_permuted * rp, one_if_dynamic); // 1 temp to allocate the mask
  VERIFY_IS_APPROX(m_permuted, m_original*rp);

  if(rows>1 && cols>1)
  {
    lp2 = lp;
    Index i = internal::random<Index>(0, rows-1);
    Index j;
    do j = internal::random<Index>(0, rows-1); while(j==i);
    lp2.applyTranspositionOnTheLeft(i, j);
    lm = lp;
    lm.row(i).swap(lm.row(j));
    VERIFY_IS_APPROX(lm, lp2.toDenseMatrix().template cast<Scalar>());

    RightPermutationType rp2 = rp;
    i = internal::random<Index>(0, cols-1);
    do j = internal::random<Index>(0, cols-1); while(j==i);
    rp2.applyTranspositionOnTheRight(i, j);
    rm = rp;
    rm.col(i).swap(rm.col(j));
    VERIFY_IS_APPROX(rm, rp2.toDenseMatrix().template cast<Scalar>());
  }
}

template<typename T>
void bug890()
{
  typedef Matrix<T, Dynamic, Dynamic> MatrixType;
  typedef Matrix<T, Dynamic, 1> VectorType;
  typedef Stride<Dynamic,Dynamic> S;
  typedef Map<MatrixType, Aligned, S> MapType;
  typedef PermutationMatrix<Dynamic> Perm;

  VectorType v1(2), v2(2), op(4), rhs(2);
  v1 << 666,667;
  op << 1,0,0,1;
  rhs << 42,42;

  Perm P(2);
  P.indices() << 1, 0;

  MapType(v1.data(),2,1,S(1,1)) = P * MapType(rhs.data(),2,1,S(1,1));
  VERIFY_IS_APPROX(v1, (P * rhs).eval());

  MapType(v1.data(),2,1,S(1,1)) = P.inverse() * MapType(rhs.data(),2,1,S(1,1));
  VERIFY_IS_APPROX(v1, (P.inverse() * rhs).eval());
}

void test_permutationmatrices()
{
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1( permutationmatrices(Matrix<float, 1, 1>()) );
    CALL_SUBTEST_2( permutationmatrices(Matrix3f()) );
    CALL_SUBTEST_3( permutationmatrices(Matrix<double,3,3,RowMajor>()) );
    CALL_SUBTEST_4( permutationmatrices(Matrix4d()) );
    CALL_SUBTEST_5( permutationmatrices(Matrix<double,40,60>()) );
    CALL_SUBTEST_6( permutationmatrices(Matrix<double,Dynamic,Dynamic,RowMajor>(20, 30)) );
    CALL_SUBTEST_7( permutationmatrices(MatrixXcf(15, 10)) );
  }
  CALL_SUBTEST_5( bug890<double>() );
}
<|endoftext|>


<commit_before>// Copyright 2015 Google Inc. All Rights Reserved.
//
// 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 "clparser.h"

#include <algorithm>
#include <assert.h>
#include <string.h>

#include "metrics.h"
#include "string_piece_util.h"

#ifdef _WIN32
#include "includes_normalize.h"
#include "string_piece.h"
#else
#include "util.h"
#endif

using namespace std;

namespace {

/// Return true if \a input ends with \a needle.
bool EndsWith(const string& input, const string& needle) {
  return (input.size() >= needle.size() &&
          input.substr(input.size() - needle.size()) == needle);
}

}  // anonymous namespace

// static
string CLParser::FilterShowIncludes(const string& line,
                                    const string& deps_prefix) {
  const string kDepsPrefixEnglish = "Note: including file: ";
  const char* in = line.c_str();
  const char* end = in + line.size();
  const string& prefix = deps_prefix.empty() ? kDepsPrefixEnglish : deps_prefix;
  if (end - in > (int)prefix.size() &&
      memcmp(in, prefix.c_str(), (int)prefix.size()) == 0) {
    in += prefix.size();
    while (*in == ' ')
      ++in;
    return line.substr(in - line.c_str());
  }
  return "";
}

// static
bool CLParser::IsSystemInclude(string path) {
  transform(path.begin(), path.end(), path.begin(), ToLowerASCII);
  // TODO: this is a heuristic, perhaps there's a better way?
  return (path.find("program files") != string::npos ||
          path.find("microsoft visual studio") != string::npos);
}

// static
bool CLParser::FilterInputFilename(string line) {
  transform(line.begin(), line.end(), line.begin(), ToLowerASCII);
  // TODO: other extensions, like .asm?
  return EndsWith(line, ".c") ||
      EndsWith(line, ".cc") ||
      EndsWith(line, ".cxx") ||
      EndsWith(line, ".cpp");
}

// static
bool CLParser::Parse(const string& output, const string& deps_prefix,
                     string* filtered_output, string* err) {
  METRIC_RECORD("CLParser::Parse");

  // Loop over all lines in the output to process them.
  assert(&output != filtered_output);
  size_t start = 0;
  bool seen_show_includes = false;
#ifdef _WIN32
  IncludesNormalize normalizer(".");
#endif

  while (start < output.size()) {
    size_t end = output.find_first_of("\r\n", start);
    if (end == string::npos)
      end = output.size();
    string line = output.substr(start, end - start);

    string include = FilterShowIncludes(line, deps_prefix);
    if (!include.empty()) {
      seen_show_includes = true;
      string normalized;
#ifdef _WIN32
      if (!normalizer.Normalize(include, &normalized, err))
        return false;
#else
      // TODO: should this make the path relative to cwd?
      normalized = include;
      uint64_t slash_bits;
      CanonicalizePath(&normalized, &slash_bits);
#endif
      if (!IsSystemInclude(normalized))
        includes_.insert(normalized);
    } else if (!seen_show_includes && FilterInputFilename(line)) {
      // Drop it.
      // TODO: if we support compiling multiple output files in a single
      // cl.exe invocation, we should stash the filename.
    } else {
      filtered_output->append(line);
      filtered_output->append("\n");
    }

    if (end < output.size() && output[end] == '\r')
      ++end;
    if (end < output.size() && output[end] == '\n')
      ++end;
    start = end;
  }

  return true;
}
<commit_msg>Filter lines ending with ".c++" in clparser<commit_after>// Copyright 2015 Google Inc. All Rights Reserved.
//
// 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 "clparser.h"

#include <algorithm>
#include <assert.h>
#include <string.h>

#include "metrics.h"
#include "string_piece_util.h"

#ifdef _WIN32
#include "includes_normalize.h"
#include "string_piece.h"
#else
#include "util.h"
#endif

using namespace std;

namespace {

/// Return true if \a input ends with \a needle.
bool EndsWith(const string& input, const string& needle) {
  return (input.size() >= needle.size() &&
          input.substr(input.size() - needle.size()) == needle);
}

}  // anonymous namespace

// static
string CLParser::FilterShowIncludes(const string& line,
                                    const string& deps_prefix) {
  const string kDepsPrefixEnglish = "Note: including file: ";
  const char* in = line.c_str();
  const char* end = in + line.size();
  const string& prefix = deps_prefix.empty() ? kDepsPrefixEnglish : deps_prefix;
  if (end - in > (int)prefix.size() &&
      memcmp(in, prefix.c_str(), (int)prefix.size()) == 0) {
    in += prefix.size();
    while (*in == ' ')
      ++in;
    return line.substr(in - line.c_str());
  }
  return "";
}

// static
bool CLParser::IsSystemInclude(string path) {
  transform(path.begin(), path.end(), path.begin(), ToLowerASCII);
  // TODO: this is a heuristic, perhaps there's a better way?
  return (path.find("program files") != string::npos ||
          path.find("microsoft visual studio") != string::npos);
}

// static
bool CLParser::FilterInputFilename(string line) {
  transform(line.begin(), line.end(), line.begin(), ToLowerASCII);
  // TODO: other extensions, like .asm?
  return EndsWith(line, ".c") ||
      EndsWith(line, ".cc") ||
      EndsWith(line, ".cxx") ||
      EndsWith(line, ".cpp") ||
      EndsWith(line, ".c++");
}

// static
bool CLParser::Parse(const string& output, const string& deps_prefix,
                     string* filtered_output, string* err) {
  METRIC_RECORD("CLParser::Parse");

  // Loop over all lines in the output to process them.
  assert(&output != filtered_output);
  size_t start = 0;
  bool seen_show_includes = false;
#ifdef _WIN32
  IncludesNormalize normalizer(".");
#endif

  while (start < output.size()) {
    size_t end = output.find_first_of("\r\n", start);
    if (end == string::npos)
      end = output.size();
    string line = output.substr(start, end - start);

    string include = FilterShowIncludes(line, deps_prefix);
    if (!include.empty()) {
      seen_show_includes = true;
      string normalized;
#ifdef _WIN32
      if (!normalizer.Normalize(include, &normalized, err))
        return false;
#else
      // TODO: should this make the path relative to cwd?
      normalized = include;
      uint64_t slash_bits;
      CanonicalizePath(&normalized, &slash_bits);
#endif
      if (!IsSystemInclude(normalized))
        includes_.insert(normalized);
    } else if (!seen_show_includes && FilterInputFilename(line)) {
      // Drop it.
      // TODO: if we support compiling multiple output files in a single
      // cl.exe invocation, we should stash the filename.
    } else {
      filtered_output->append(line);
      filtered_output->append("\n");
    }

    if (end < output.size() && output[end] == '\r')
      ++end;
    if (end < output.size() && output[end] == '\n')
      ++end;
    start = end;
  }

  return true;
}
<|endoftext|>


<commit_before>#include "command.h"

Command::Command(const char* text) {

	int i=0;
	// turn the string into a stream
	stringstream ssin(*text);
	//put the stream to the array
	while (i<argc ){
		ssin >> argv[i];
		i+=1;
	}

}

virtual Command::~Command() {
	// TODO(asarlidou) implement
}

char* const* Command::getArgs() const {
	return argv;
}

const char* Command::getCommand() const {
	return argc[0];
}

const char* Command::getLast() const {
	return argv[argc - 1];
}<commit_msg>Command parsing rework<commit_after>#include "command.h"

#include "string.h"

Command::Command(const char* text) {

	char buff[256];
	char* array[256];

	int i = 0, ibuff = 0, iarray = 0;

	while(true) {

		if (text[i] != ' ' && text[i] != '\0') {

			buff[ibuff] = text[i];
			ibuff += 1;

		}else if(ibuff > 0) {

			buff[ibuff] = '\0';
			ibuff += 1;

			char* arg = new char[ibuff];
			String::copy(arg, buff);

			array[iarray] = arg;
			iarray += 1;

			ibuff = 0;
		}

		if(text[i] == '\0') {
			break;
		}

		i += 1;
	}

	array[i] = nullptr;

	argc = i;
	args = new char*[i+1];
	String::copy(args, array);

}

virtual Command::~Command() {
	// TODO(asarlidou) implement
}

char* const* Command::getArgs() const {
	return argv;
}

const char* Command::getCommand() const {
	return argc[0];
}

const char* Command::getLast() const {
	return argv[argc - 1];
}<|endoftext|>


<commit_before>/*
 * Clever programming language
 * Copyright (c) 2011 Clever Team
 *
 * 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.
 *
 * $Id$
 */

#include <iostream>
#include <cstdlib>
#include <vector>
#include "compiler.h"
#include "ast.h"
#include "int.h"
#include "double.h"
#include "astvisitor.h"
#include "typetable.h"

namespace clever {

PackageManager Compiler::s_pkgmanager;
FunctionTable Compiler::s_func_table;
TypeMap TypeTable::s_type_table;

/**
 * Initializes the compiler data
 */
void Compiler::Init(ast::Node* nodes) throw() {
	m_ast = nodes;
	/**
	 * Load package list
	 */
	s_pkgmanager.Init(&s_func_table);

	/**
	 * Load the primitive data types
	 */
	loadTypes();

	m_visitor = new ast::ASTVisitor;
}

/**
 * Loads native types
 */
void Compiler::loadTypes() throw() {
	g_int_type->Init();
	g_double_type->Init();

	TypeTable::insert(CSTRING("Int"), g_int_type);
	TypeTable::insert(CSTRING("Double"), g_double_type);
}

OpcodeList& Compiler::getOpcodes() throw() {
	return m_visitor->get_opcodes();
}

/**
 * Deallocs memory used by compiler data
 */
Compiler::~Compiler() {
	FunctionTable::const_iterator it = s_func_table.begin(), end_func(s_func_table.end());

	/**
	 * Deallocs memory used by global function table entries
	 */
	while (it != end_func) {
		delete it->second;
		++it;
	}

	TypeTable::clear();

	s_pkgmanager.shutdown();

	delete m_visitor;

	delete m_ast;
}

/**
 * Collects all opcode
 */
void Compiler::buildIR() throw() {
	ast::NodeList& ast_nodes = m_ast->getNodes();
	ast::NodeList::iterator it = ast_nodes.begin(), end(ast_nodes.end());

	m_visitor->init();

	/**
	 * Iterating over TopNode AST node
	 */
	while (it != end) {
		(*it)->accept(*m_visitor);
		++it;
	}

	m_visitor->shutdown();

	m_ast->clearNodes();
}

/**
 * Displays an error message
 */
void Compiler::error(std::string message) throw() {
	std::cerr << "Compile error: " << message << std::endl;
	exit(1);
}

/**
 * Performs a type compatible checking
 */
bool Compiler::checkCompatibleTypes(Value* lhs, Value* rhs) throw() {
	/**
	 * Constants with different type cannot performs operation
	 */
	if (lhs->isPrimitive() && lhs->hasSameKind(rhs) && !lhs->hasSameType(rhs)) {
		return false;
	}
	return true;
}

/**
 * Performs a constant folding optimization
 */
Value* Compiler::constantFolding(int op, Value* lhs, Value* rhs) throw() {

#define DO_NUM_OPERATION(_op, type, x, y) \
	if (x->is##type()) return new Value(x->get##type() _op y->get##type());

#define DO_STR_OPERATION(_op, x, y) \
	if (x->isString()) return new Value(CSTRING(x->getString() _op y->getString()));

	/**
	 * Check if the variable value can be predicted
	 */
	if ((lhs->hasName() && lhs->isModified()) || (rhs->hasName() && rhs->isModified())) {
		return NULL;
	}

	switch (op) {
		case ast::PLUS:
			DO_NUM_OPERATION(+, Integer, lhs, rhs);
			DO_STR_OPERATION(+, lhs, rhs);
			DO_NUM_OPERATION(+, Double, lhs, rhs);
			break;
		case ast::MINUS:
			DO_NUM_OPERATION(-, Integer, lhs, rhs);
			DO_NUM_OPERATION(-, Double, lhs, rhs);
			break;
		case ast::DIV:
			DO_NUM_OPERATION(/, Integer, lhs, rhs);
			DO_NUM_OPERATION(/, Double, lhs, rhs);
			break;
		case ast::MULT:
			DO_NUM_OPERATION(*, Integer, lhs, rhs);
			DO_NUM_OPERATION(*, Double, lhs, rhs);
			break;
		case ast::OR:
			DO_NUM_OPERATION(|, Integer, lhs, rhs);
			break;
		case ast::XOR:
			DO_NUM_OPERATION(^, Integer, lhs, rhs);
			break;
		case ast::AND:
			DO_NUM_OPERATION(&, Integer, lhs, rhs);
			break;
		case ast::GREATER:
			DO_NUM_OPERATION(>, Integer, lhs, rhs);
			DO_NUM_OPERATION(>, Double, lhs, rhs);
			break;
		case ast::LESS:
			DO_NUM_OPERATION(<, Integer, lhs, rhs);
			DO_NUM_OPERATION(<, Double, lhs, rhs);
			break;
		case ast::GREATER_EQUAL:
			DO_NUM_OPERATION(>=, Integer, lhs, rhs);
			DO_NUM_OPERATION(>=, Double, lhs, rhs);
			break;
		case ast::LESS_EQUAL:
			DO_NUM_OPERATION(<=, Integer, lhs, rhs);
			DO_NUM_OPERATION(<=, Double, lhs, rhs);
			break;
		case ast::EQUAL:
			DO_NUM_OPERATION(==, Integer, lhs, rhs);
			DO_NUM_OPERATION(==, Double, lhs, rhs);
			break;
		case ast::NOT_EQUAL:
			DO_NUM_OPERATION(!=, Integer, lhs, rhs);
			DO_NUM_OPERATION(!=, Double, lhs, rhs);
			break;
		case ast::MOD:
			DO_NUM_OPERATION(%, Integer, lhs, rhs);
			break;
	}
	return NULL;
}

} // clever
<commit_msg>- Fix check<commit_after>/*
 * Clever programming language
 * Copyright (c) 2011 Clever Team
 *
 * 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.
 *
 * $Id$
 */

#include <iostream>
#include <cstdlib>
#include <vector>
#include "compiler.h"
#include "ast.h"
#include "int.h"
#include "double.h"
#include "astvisitor.h"
#include "typetable.h"

namespace clever {

PackageManager Compiler::s_pkgmanager;
FunctionTable Compiler::s_func_table;
TypeMap TypeTable::s_type_table;

/**
 * Initializes the compiler data
 */
void Compiler::Init(ast::Node* nodes) throw() {
	m_ast = nodes;
	/**
	 * Load package list
	 */
	s_pkgmanager.Init(&s_func_table);

	/**
	 * Load the primitive data types
	 */
	loadTypes();

	m_visitor = new ast::ASTVisitor;
}

/**
 * Loads native types
 */
void Compiler::loadTypes() throw() {
	g_int_type->Init();
	g_double_type->Init();

	TypeTable::insert(CSTRING("Int"), g_int_type);
	TypeTable::insert(CSTRING("Double"), g_double_type);
}

OpcodeList& Compiler::getOpcodes() throw() {
	return m_visitor->get_opcodes();
}

/**
 * Deallocs memory used by compiler data
 */
Compiler::~Compiler() {
	FunctionTable::const_iterator it = s_func_table.begin(), end_func(s_func_table.end());

	/**
	 * Deallocs memory used by global function table entries
	 */
	while (it != end_func) {
		delete it->second;
		++it;
	}

	TypeTable::clear();

	s_pkgmanager.shutdown();

	delete m_visitor;

	delete m_ast;
}

/**
 * Collects all opcode
 */
void Compiler::buildIR() throw() {
	ast::NodeList& ast_nodes = m_ast->getNodes();
	ast::NodeList::iterator it = ast_nodes.begin(), end(ast_nodes.end());

	m_visitor->init();

	/**
	 * Iterating over TopNode AST node
	 */
	while (it != end) {
		(*it)->accept(*m_visitor);
		++it;
	}

	m_visitor->shutdown();

	m_ast->clearNodes();
}

/**
 * Displays an error message
 */
void Compiler::error(std::string message) throw() {
	std::cerr << "Compile error: " << message << std::endl;
	exit(1);
}

/**
 * Performs a type compatible checking
 */
bool Compiler::checkCompatibleTypes(Value* lhs, Value* rhs) throw() {
	/**
	 * Constants with different type cannot performs operation
	 */
	if (lhs->isPrimitive() && rhs->isPrimitive() && !lhs->hasSameType(rhs)) {
		return false;
	}
	return true;
}

/**
 * Performs a constant folding optimization
 */
Value* Compiler::constantFolding(int op, Value* lhs, Value* rhs) throw() {

#define DO_NUM_OPERATION(_op, type, x, y) \
	if (x->is##type()) return new Value(x->get##type() _op y->get##type());

#define DO_STR_OPERATION(_op, x, y) \
	if (x->isString()) return new Value(CSTRING(x->getString() _op y->getString()));

	/**
	 * Check if the variable value can be predicted
	 */
	if ((lhs->hasName() && lhs->isModified()) || (rhs->hasName() && rhs->isModified())) {
		return NULL;
	}

	switch (op) {
		case ast::PLUS:
			DO_NUM_OPERATION(+, Integer, lhs, rhs);
			DO_STR_OPERATION(+, lhs, rhs);
			DO_NUM_OPERATION(+, Double, lhs, rhs);
			break;
		case ast::MINUS:
			DO_NUM_OPERATION(-, Integer, lhs, rhs);
			DO_NUM_OPERATION(-, Double, lhs, rhs);
			break;
		case ast::DIV:
			DO_NUM_OPERATION(/, Integer, lhs, rhs);
			DO_NUM_OPERATION(/, Double, lhs, rhs);
			break;
		case ast::MULT:
			DO_NUM_OPERATION(*, Integer, lhs, rhs);
			DO_NUM_OPERATION(*, Double, lhs, rhs);
			break;
		case ast::OR:
			DO_NUM_OPERATION(|, Integer, lhs, rhs);
			break;
		case ast::XOR:
			DO_NUM_OPERATION(^, Integer, lhs, rhs);
			break;
		case ast::AND:
			DO_NUM_OPERATION(&, Integer, lhs, rhs);
			break;
		case ast::GREATER:
			DO_NUM_OPERATION(>, Integer, lhs, rhs);
			DO_NUM_OPERATION(>, Double, lhs, rhs);
			break;
		case ast::LESS:
			DO_NUM_OPERATION(<, Integer, lhs, rhs);
			DO_NUM_OPERATION(<, Double, lhs, rhs);
			break;
		case ast::GREATER_EQUAL:
			DO_NUM_OPERATION(>=, Integer, lhs, rhs);
			DO_NUM_OPERATION(>=, Double, lhs, rhs);
			break;
		case ast::LESS_EQUAL:
			DO_NUM_OPERATION(<=, Integer, lhs, rhs);
			DO_NUM_OPERATION(<=, Double, lhs, rhs);
			break;
		case ast::EQUAL:
			DO_NUM_OPERATION(==, Integer, lhs, rhs);
			DO_NUM_OPERATION(==, Double, lhs, rhs);
			break;
		case ast::NOT_EQUAL:
			DO_NUM_OPERATION(!=, Integer, lhs, rhs);
			DO_NUM_OPERATION(!=, Double, lhs, rhs);
			break;
		case ast::MOD:
			DO_NUM_OPERATION(%, Integer, lhs, rhs);
			break;
	}
	return NULL;
}

} // clever
<|endoftext|>


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

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkPolylineMaskImageFilterTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include <itkImage.h>
#include <itkImageRegionIteratorWithIndex.h>
#include <itkPolylineMaskImageFilter.h>
#include <itkPolyLineParametricPath.h>
#include <itkEllipseSpatialObject.h>
#include <itkSpatialObjectToImageFilter.h>
#include <itkImageFileWriter.h>

int itkPolylineMaskImageFilterTest(int argc , char * argv [] )
{

  // Define the dimension of the images
  const unsigned int iDimension = 3;

  //Define the dimension of the polyline
  const unsigned int pDimension = 2;

  // Declare the types of the images
  typedef itk::Image<unsigned short, iDimension>     inputImageType;
  typedef itk::Image<unsigned short, iDimension>     outputImageType;
  typedef itk::Vector<double, iDimension>            inputVectorType;
  typedef itk::PolyLineParametricPath<pDimension>    inputPolylineType;

  // Declare the type of the index to access images
  typedef itk::Index<iDimension>         inputIndexType;

  // Declare the type of the size
  typedef itk::Size<iDimension>          inputSizeType;

  // Declare the type of the Region
  typedef itk::ImageRegion<iDimension>   inputRegionType;

  // Create vector
  inputVectorType   inputUpVector,inputViewVector;

  // Create polyline
  inputPolylineType::Pointer inputPolyline   = inputPolylineType::New();
  std::cout<<"Generating the synthetic object...."<<std::endl;
  //Generate ellipse image

  typedef itk::EllipseSpatialObject<2>   EllipseType;
  EllipseType::Pointer ellipse = EllipseType::New();
  EllipseType::TransformType::OffsetType offset;
  offset.Fill(15);
  ellipse->GetObjectToParentTransform()->SetOffset(offset);
  ellipse->ComputeObjectToWorldTransform();
  ellipse->SetRadius(15);

  std::cout<<"Generating the image of the object...."<<std::endl;

  typedef itk::SpatialObjectToImageFilter<EllipseType,inputImageType> SpatialObjectToImageFilterType;
  SpatialObjectToImageFilterType::Pointer imageFilter = SpatialObjectToImageFilterType::New();

  inputImageType::SizeType size;
  size[0]=40;
  size[1]=40;
  size[2]=30;

  imageFilter->SetSize(size);
  imageFilter->SetInput(ellipse);
  imageFilter->SetInsideValue(2);
  imageFilter->SetOutsideValue(0);
  imageFilter->Update();

  //Create images
  inputImageType::Pointer inputImage    = inputImageType::New();
  outputImageType::Pointer outputImage  = outputImageType::New();

  std::cout << "Generating the polyline..." << std::endl;
  //Initialize the polyline
  typedef inputPolylineType::VertexType VertexType;

  // Add vertices to the polyline
  VertexType v;
  v[0] = 8;
  v[1] = 8;
  inputPolyline->AddVertex(v);

  v[0] = 23;
  v[1] = 8;
  inputPolyline->AddVertex(v);

  v[0] = 23;
  v[1] = 23;
  inputPolyline->AddVertex(v);

  v[0] = 8;
  v[1] = 23;
  inputPolyline->AddVertex(v);

  std::cout << "Generating the view vector " << std::endl;

  // View vector
  inputViewVector[0] = 0;
  inputViewVector[1] = 0;
  inputViewVector[2] = -1;

  // Up vector
  inputUpVector[0] = 1;
  inputUpVector[1] = 0;
  inputUpVector[2] = 0;

  // Declare the type for the Mask image filter
  typedef itk::PolylineMaskImageFilter<
                           inputImageType, inputPolylineType,
                           inputVectorType,
                           outputImageType  >     inputFilterType;

  typedef inputFilterType::PointType PointType;
  typedef inputFilterType::ProjPlanePointType ProjPlanePointType;

  std::cout<< "Generating the filter....................." << std::endl;

  // Create a mask  Filter
  inputFilterType::Pointer filter = inputFilterType::New();

  //Connect the input image
  filter->SetInput1    ( imageFilter->GetOutput());

  // Connect the Polyline
  filter->SetInput2    ( inputPolyline );

  // Connect the Viewing direction vector
  filter->SetViewVector   ( inputViewVector );

  // Connect the Viewing direction vector
  filter->SetUpVector   ( inputUpVector );

  // camera center point
  PointType cameraCenterPoint;
  cameraCenterPoint[0] = 15;
  cameraCenterPoint[1] = 15;
  cameraCenterPoint[2] = 60;

  filter->SetCameraCenterPoint   ( cameraCenterPoint );

  // camera focal distance
  filter->SetFocalDistance(15);

  // camera focal point in the projection plane
  ProjPlanePointType focalpoint;
  focalpoint[0] = 15;
  focalpoint[1] = 15;
  filter->SetFocalPoint(focalpoint);

  // Get the Smart Pointer to the Filter Output
  outputImage = filter->GetOutput();
  // Execute the filter
  filter->Update();
  return 0;

}

<commit_msg>BUG: using uninitialzed image pointer<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkPolylineMaskImageFilterTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include <itkImage.h>
#include <itkImageRegionIteratorWithIndex.h>
#include <itkPolylineMaskImageFilter.h>
#include <itkPolyLineParametricPath.h>
#include <itkEllipseSpatialObject.h>
#include <itkSpatialObjectToImageFilter.h>
#include <itkImageFileWriter.h>

int itkPolylineMaskImageFilterTest(int argc , char * argv [] )
{

  // Define the dimension of the images
  const unsigned int iDimension = 3;

  //Define the dimension of the polyline
  const unsigned int pDimension = 2;

  // Declare the types of the images
  typedef itk::Image<unsigned short, iDimension>     inputImageType;
  typedef itk::Image<unsigned short, iDimension>     outputImageType;
  typedef itk::Vector<double, iDimension>            inputVectorType;
  typedef itk::PolyLineParametricPath<pDimension>    inputPolylineType;

  // Declare the type of the index to access images
  typedef itk::Index<iDimension>         inputIndexType;

  // Declare the type of the size
  typedef itk::Size<iDimension>          inputSizeType;

  // Declare the type of the Region
  typedef itk::ImageRegion<iDimension>   inputRegionType;

  // Create vector
  inputVectorType   inputUpVector,inputViewVector;

  // Create polyline
  inputPolylineType::Pointer inputPolyline   = inputPolylineType::New();
  std::cout<<"Generating the synthetic object...."<<std::endl;
  //Generate ellipse image

  typedef itk::EllipseSpatialObject<2>   EllipseType;
  EllipseType::Pointer ellipse = EllipseType::New();
  EllipseType::TransformType::OffsetType offset;
  offset.Fill(15);
  ellipse->GetObjectToParentTransform()->SetOffset(offset);
  ellipse->ComputeObjectToWorldTransform();
  ellipse->SetRadius(15);

  std::cout<<"Generating the image of the object...."<<std::endl;

  typedef itk::SpatialObjectToImageFilter<EllipseType,inputImageType> SpatialObjectToImageFilterType;
  SpatialObjectToImageFilterType::Pointer imageFilter = SpatialObjectToImageFilterType::New();

  inputImageType::SizeType size;
  size[0]=40;
  size[1]=40;
  size[2]=30;

  imageFilter->SetSize(size);
  imageFilter->SetInput(ellipse);
  imageFilter->SetInsideValue(2);
  imageFilter->SetOutsideValue(0);
  imageFilter->Update();

  //Create images
  inputImageType::Pointer inputImage    = inputImageType::New();
  outputImageType::Pointer outputImage  = outputImageType::New();

  std::cout << "Generating the polyline..." << std::endl;
  //Initialize the polyline
  typedef inputPolylineType::VertexType VertexType;

  // Add vertices to the polyline
  VertexType v;
  v[0] = 8;
  v[1] = 8;
  inputPolyline->AddVertex(v);

  v[0] = 23;
  v[1] = 8;
  inputPolyline->AddVertex(v);

  v[0] = 23;
  v[1] = 23;
  inputPolyline->AddVertex(v);

  v[0] = 8;
  v[1] = 23;
  inputPolyline->AddVertex(v);

  std::cout << "Generating the view vector " << std::endl;

  // View vector
  inputViewVector[0] = 0;
  inputViewVector[1] = 0;
  inputViewVector[2] = -1;

  // Up vector
  inputUpVector[0] = 1;
  inputUpVector[1] = 0;
  inputUpVector[2] = 0;

  // Declare the type for the Mask image filter
  typedef itk::PolylineMaskImageFilter<
                           inputImageType, inputPolylineType,
                           inputVectorType,
                           outputImageType  >     inputFilterType;

  typedef inputFilterType::PointType PointType;
  typedef inputFilterType::ProjPlanePointType ProjPlanePointType;

  std::cout<< "Generating the filter....................." << std::endl;

  // Create a mask  Filter
  inputFilterType::Pointer filter = inputFilterType::New();

  //Connect the input image
  filter->SetInput1    ( imageFilter->GetOutput());

  // Connect the Polyline
  filter->SetInput2    ( inputPolyline );

  // Connect the Viewing direction vector
  filter->SetViewVector   ( inputViewVector );

  // Connect the Viewing direction vector
  filter->SetUpVector   ( inputUpVector );

  // camera center point
  PointType cameraCenterPoint;
  cameraCenterPoint[0] = 15;
  cameraCenterPoint[1] = 15;
  cameraCenterPoint[2] = 60;

  filter->SetCameraCenterPoint   ( cameraCenterPoint );

  // camera focal distance
  filter->SetFocalDistance(15);

  // camera focal point in the projection plane
  ProjPlanePointType focalpoint;
  focalpoint[0] = 15;
  focalpoint[1] = 15;
  filter->SetFocalPoint(focalpoint);
  filter->Update();

  return 0;

}

<|endoftext|>