<commit_before>// MGenTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "MGenTest.h"
#include "../MGen/GLibrary/GLib.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// The one and only application object

CWinApp theApp;

using namespace std;

CString current_dir, full_url, server, url;
DWORD service;
WORD port;
ofstream logfile;
int ci = 0;
int nRetCode = 0;

/*
string url_encode(const string &value) {
	ostringstream escaped;
	escaped.fill('0');
	escaped << hex;

	for (string::const_iterator i = value.begin(), n = value.end(); i != n; ++i) {
		string::value_type c = (*i);

		// Keep alphanumeric and other accepted characters intact
		if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {
			escaped << c;
			continue;
		}

		// Any other characters are percent-encoded
		escaped << uppercase;
		escaped << '%' << setw(2) << int((unsigned char)c);
		escaped << nouppercase;
	}

	return escaped.str();
}

void HTTPPost(CString server, WORD port, CString url, CString data) {
	cout << "HTTPPost to server " << server << " port " << port << " url " << url << " : " << data << "\n";
	CString strHeaders = "Content-Type: application/x-www-form-urlencoded";
	try {
		char szBuf [2550];
		DWORD dwRet;
		CInternetSession session;
		CHttpConnection* pConnection = session.GetHttpConnection(server, port);
		CHttpFile* pFile = pConnection->OpenRequest(CHttpConnection::HTTP_VERB_POST, url);
		pFile->AddRequestHeaders(strHeaders);
		data = url_encode(data.GetBuffer()).c_str();
		cout << "HTTPPost to server " << server << " port " << port << " url " << url << " : " << data << "\n";
		pFile->SendRequestEx(data.GetLength());
		pFile->Write(data, data.GetLength());
		//BOOL result = pFile->SendRequest(strHeaders, (LPVOID)(LPCTSTR)data, data.GetLength());
		pFile->QueryInfoStatusCode(dwRet);
		cout << "HTTP return code: " << dwRet << "\n";
		if (dwRet == HTTP_STATUS_OK) {
			UINT nRead = pFile->Read(szBuf, 2550);
			if (nRead > 0) {
				cout << "HTTP result: " << szBuf << "\n";
			}
		}
	}
	catch (CInternetException *e) {
		//e->ReportError();
		TCHAR   szCause[2550];
		e->GetErrorMessage(szCause, 2550);
		cout << "Error when sending HTTP request: " << szCause << "\n";
		e->Delete();
	}
}
*/

void Run(CString fname, CString par, int delay) {
	SHELLEXECUTEINFO sei = { 0 };
	sei.cbSize = sizeof(SHELLEXECUTEINFO);
	sei.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI;
	sei.hwnd = NULL;
	sei.lpVerb = NULL;
	sei.lpFile = fname;
	sei.lpParameters = par;
	sei.lpDirectory = NULL;
	sei.nShow = SW_SHOWNORMAL;
	sei.hInstApp = NULL;
	ShellExecuteEx(&sei);
	WaitForSingleObject(sei.hProcess, delay);
}

void Log(CString st, int level = 0) {
	cout << st;
	logfile << st;
	if (ci && level > 0) {
		CString cat;
		if (level == 1) cat = "Information";
		if (level == 2) cat = "Warning";
		if (level == 3) cat = "Error";
		CString par = "AddMessage \"" + st + "\" -Category " + cat;
		Run("appveyor", par, 1000);
	}
}

CString file(CString fname) {
	CString st, st2;
	ifstream fs;
	// Check file exists
	if (!CGLib::fileExists(fname)) {
		cout << "Not found file " << fname << "\n";
	}
	fs.open(fname);
	char pch[2550];
	while (fs.good()) {
		// Get line
		fs.getline(pch, 2550);
		st2 = pch;
		if (st2 != "") {
			st += "- " + st2 + "\n";
		}
	}
	fs.close();
	return st;
}

void ClearBuffer() {
	fstream fs;
	fs.open("autotest\\buffer.log", ios::out);
	fs.close();
}

void PublishTest(CString tname, int result, int tpassed) {
	CString st;
	CString st2;
	st2.Format("%s: code %d in %d ms\n", tname, result, tpassed);
	if (result) {
		nRetCode = 2;
		Log(st2, 3);
	}
	else {
		Log(st2, 1);
	}

	// Show errors
	CString errors = file("autotest/buffer.log");
	cout << errors;

	if (ci) {
		errors.Replace("\n- ", "\\n ");
		CString cat = "Passed";
		if (result) cat = "Failed";
		st.Format("UpdateTest \"%s\" -Framework MSTest -FileName MGen.exe -Duration %d -Outcome %s -ErrorMessage \"%d. %s\"", tname, tpassed, cat, result, errors);
		Run("appveyor", st, 1000);
		st.Format("UpdateTest \"%s\" -StdErr \"%s\"", tname, errors);
		Run("appveyor", st, 1000);
	}

	/*
	// Send HTTP
	st.Format("{"
		" \"testName\": \"%s\","
		" \"testFramework\" : \"MSTest\","
		" \"fileName\" : \"MGen.exe\","
		" \"outcome\" : \"%s\","
		" \"durationMilliseconds\" : \"%d\","
		" \"ErrorMessage\" : \"%s\","
		" \"ErrorStackTrace\" : \"\","
		" \"StdOut\" : \"\","
		" \"StdErr\" : \"\""
		" }", tname, cat, tpassed, errors);
	if (ci) {
		HTTPPost(server, port, url + "api/tests", st);
	}
	*/
}

void LoadConfig() {
	milliseconds time_start, time_stop;
	CString fname = "autotest\\test.txt";
	// Check file exists
	if (!CGLib::fileExists(fname)) {
		cout << "Not found file " << fname << "\n";
	}
	ifstream fs;
	fs.open(fname);
	LPDWORD ecode = new DWORD;
	CString st, st2;
	char pch[2550];
	int pos = 0;
	int passed;
	while (fs.good()) {
		fs.getline(pch, 2550);
		st = pch;
		pos = st.Find("#");
		if (pos != -1) st = st.Left(pos);
		st.Trim();
		if (st.GetLength()) {
			ClearBuffer();
			if (ci) Run("appveyor", "AddTest \"" + st + "\" -Framework MSTest -FileName MGen.exe -Outcome Running", 1000);
			Log("Starting test config: " + st + "\n");
			//::ShellExecute(GetDesktopWindow(), "open", "MGen", "-test " + st, NULL, SW_SHOWNORMAL);
			st2 = "-test " + st;
			SHELLEXECUTEINFO sei = { 0 };
			sei.cbSize = sizeof(SHELLEXECUTEINFO);
			sei.fMask = SEE_MASK_NOCLOSEPROCESS;
			sei.hwnd = NULL;
			sei.lpVerb = NULL;
			sei.lpFile = "MGen.exe";
			sei.lpParameters = st2;
			sei.lpDirectory = NULL;
			sei.nShow = SW_SHOW;
			sei.hInstApp = NULL;
			time_start = duration_cast< milliseconds >(system_clock::now().time_since_epoch());
			ShellExecuteEx(&sei);
			if (WaitForSingleObject(sei.hProcess, 60000) == WAIT_TIMEOUT) {
				Log(st + ": Timeout waiting for process\n", 3);
				exit(1);
			}

			time_stop = duration_cast< milliseconds >(system_clock::now().time_since_epoch());
			passed = static_cast<int>((time_stop - time_start).count());
			GetExitCodeProcess(sei.hProcess, ecode);
			PublishTest(st, *ecode, passed);
		}
	}
	delete ecode;
	fs.close();
}

int test() {
	//full_url = "http://my.test.server:882/some/path/script.php?parameters=123";
	//AfxParseURL(full_url, service, server, url, port);
	//ci = 1;
	if (getenv("APPVEYOR_PROJECT_NAME") != NULL) {
		ci = 1;
		//if (getenv("APPVEYOR_API_URL") != NULL) full_url = getenv("APPVEYOR_API_URL");
		//AfxParseURL(full_url, service, server, url, port);
	}
	logfile.open("autotest\\test.log", ios_base::app);

	TCHAR buffer[MAX_PATH];
	GetCurrentDirectory(MAX_PATH, buffer);
	current_dir = string(buffer).c_str();
	Log("Current dir: " + current_dir + "\n");

	LoadConfig();
	logfile.close();
	// Do not pause if continuous integration
	if (!ci) {
		cout << "Press any key to continue... ";
		_getch();
	}
	return 0;
}

int main()
{
    HMODULE hModule = ::GetModuleHandle(nullptr);

    if (hModule != nullptr)
    {
        // initialize MFC and print and error on failure
        if (!AfxWinInit(hModule, nullptr, ::GetCommandLine(), 0))
        {
            // TODO: change error code to suit your needs
            wprintf(L"Fatal Error: MFC initialization failed\n");
            nRetCode = 1;
        }
        else
        {
					test();
				}
    }
    else
    {
        // TODO: change error code to suit your needs
        wprintf(L"Fatal Error: GetModuleHandle failed\n");
        nRetCode = 1;
    }

    return nRetCode;
}
<commit_msg>MgenTest: Try br in errors<commit_after>// MGenTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "MGenTest.h"
#include "../MGen/GLibrary/GLib.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// The one and only application object

CWinApp theApp;

using namespace std;

CString current_dir, full_url, server, url;
DWORD service;
WORD port;
ofstream logfile;
int ci = 0;
int nRetCode = 0;

/*
string url_encode(const string &value) {
	ostringstream escaped;
	escaped.fill('0');
	escaped << hex;

	for (string::const_iterator i = value.begin(), n = value.end(); i != n; ++i) {
		string::value_type c = (*i);

		// Keep alphanumeric and other accepted characters intact
		if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {
			escaped << c;
			continue;
		}

		// Any other characters are percent-encoded
		escaped << uppercase;
		escaped << '%' << setw(2) << int((unsigned char)c);
		escaped << nouppercase;
	}

	return escaped.str();
}

void HTTPPost(CString server, WORD port, CString url, CString data) {
	cout << "HTTPPost to server " << server << " port " << port << " url " << url << " : " << data << "\n";
	CString strHeaders = "Content-Type: application/x-www-form-urlencoded";
	try {
		char szBuf [2550];
		DWORD dwRet;
		CInternetSession session;
		CHttpConnection* pConnection = session.GetHttpConnection(server, port);
		CHttpFile* pFile = pConnection->OpenRequest(CHttpConnection::HTTP_VERB_POST, url);
		pFile->AddRequestHeaders(strHeaders);
		data = url_encode(data.GetBuffer()).c_str();
		cout << "HTTPPost to server " << server << " port " << port << " url " << url << " : " << data << "\n";
		pFile->SendRequestEx(data.GetLength());
		pFile->Write(data, data.GetLength());
		//BOOL result = pFile->SendRequest(strHeaders, (LPVOID)(LPCTSTR)data, data.GetLength());
		pFile->QueryInfoStatusCode(dwRet);
		cout << "HTTP return code: " << dwRet << "\n";
		if (dwRet == HTTP_STATUS_OK) {
			UINT nRead = pFile->Read(szBuf, 2550);
			if (nRead > 0) {
				cout << "HTTP result: " << szBuf << "\n";
			}
		}
	}
	catch (CInternetException *e) {
		//e->ReportError();
		TCHAR   szCause[2550];
		e->GetErrorMessage(szCause, 2550);
		cout << "Error when sending HTTP request: " << szCause << "\n";
		e->Delete();
	}
}
*/

void Run(CString fname, CString par, int delay) {
	SHELLEXECUTEINFO sei = { 0 };
	sei.cbSize = sizeof(SHELLEXECUTEINFO);
	sei.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI;
	sei.hwnd = NULL;
	sei.lpVerb = NULL;
	sei.lpFile = fname;
	sei.lpParameters = par;
	sei.lpDirectory = NULL;
	sei.nShow = SW_SHOWNORMAL;
	sei.hInstApp = NULL;
	ShellExecuteEx(&sei);
	WaitForSingleObject(sei.hProcess, delay);
}

void Log(CString st, int level = 0) {
	cout << st;
	logfile << st;
	if (ci && level > 0) {
		CString cat;
		if (level == 1) cat = "Information";
		if (level == 2) cat = "Warning";
		if (level == 3) cat = "Error";
		CString par = "AddMessage \"" + st + "\" -Category " + cat;
		Run("appveyor", par, 1000);
	}
}

CString file(CString fname) {
	CString st, st2;
	ifstream fs;
	// Check file exists
	if (!CGLib::fileExists(fname)) {
		cout << "Not found file " << fname << "\n";
	}
	fs.open(fname);
	char pch[2550];
	while (fs.good()) {
		// Get line
		fs.getline(pch, 2550);
		st2 = pch;
		if (st2 != "") {
			st += "- " + st2 + "\n";
		}
	}
	fs.close();
	return st;
}

void ClearBuffer() {
	fstream fs;
	fs.open("autotest\\buffer.log", ios::out);
	fs.close();
}

void PublishTest(CString tname, int result, int tpassed) {
	CString st;
	CString st2;
	st2.Format("%s: code %d in %d ms\n", tname, result, tpassed);
	if (result) {
		nRetCode = 2;
		Log(st2, 3);
	}
	else {
		Log(st2, 1);
	}

	// Show errors
	CString errors = file("autotest/buffer.log");
	cout << errors;

	if (ci) {
		errors.Replace("\n- ", "<br> ");
		CString cat = "Passed";
		if (result) cat = "Failed";
		st.Format("UpdateTest \"%s\" -Framework MSTest -FileName MGen.exe -Duration %d -Outcome %s -ErrorMessage \"%d. %s\"", tname, tpassed, cat, result, errors);
		Run("appveyor", st, 1000);
		st.Format("UpdateTest \"%s\" -StdErr \"%s\"", tname, errors);
		Run("appveyor", st, 1000);
	}

	/*
	// Send HTTP
	st.Format("{"
		" \"testName\": \"%s\","
		" \"testFramework\" : \"MSTest\","
		" \"fileName\" : \"MGen.exe\","
		" \"outcome\" : \"%s\","
		" \"durationMilliseconds\" : \"%d\","
		" \"ErrorMessage\" : \"%s\","
		" \"ErrorStackTrace\" : \"\","
		" \"StdOut\" : \"\","
		" \"StdErr\" : \"\""
		" }", tname, cat, tpassed, errors);
	if (ci) {
		HTTPPost(server, port, url + "api/tests", st);
	}
	*/
}

void LoadConfig() {
	milliseconds time_start, time_stop;
	CString fname = "autotest\\test.txt";
	// Check file exists
	if (!CGLib::fileExists(fname)) {
		cout << "Not found file " << fname << "\n";
	}
	ifstream fs;
	fs.open(fname);
	LPDWORD ecode = new DWORD;
	CString st, st2;
	char pch[2550];
	int pos = 0;
	int passed;
	while (fs.good()) {
		fs.getline(pch, 2550);
		st = pch;
		pos = st.Find("#");
		if (pos != -1) st = st.Left(pos);
		st.Trim();
		if (st.GetLength()) {
			ClearBuffer();
			if (ci) Run("appveyor", "AddTest \"" + st + "\" -Framework MSTest -FileName MGen.exe -Outcome Running", 1000);
			Log("Starting test config: " + st + "\n");
			//::ShellExecute(GetDesktopWindow(), "open", "MGen", "-test " + st, NULL, SW_SHOWNORMAL);
			st2 = "-test " + st;
			SHELLEXECUTEINFO sei = { 0 };
			sei.cbSize = sizeof(SHELLEXECUTEINFO);
			sei.fMask = SEE_MASK_NOCLOSEPROCESS;
			sei.hwnd = NULL;
			sei.lpVerb = NULL;
			sei.lpFile = "MGen.exe";
			sei.lpParameters = st2;
			sei.lpDirectory = NULL;
			sei.nShow = SW_SHOW;
			sei.hInstApp = NULL;
			time_start = duration_cast< milliseconds >(system_clock::now().time_since_epoch());
			ShellExecuteEx(&sei);
			if (WaitForSingleObject(sei.hProcess, 60000) == WAIT_TIMEOUT) {
				Log(st + ": Timeout waiting for process\n", 3);
				exit(1);
			}

			time_stop = duration_cast< milliseconds >(system_clock::now().time_since_epoch());
			passed = static_cast<int>((time_stop - time_start).count());
			GetExitCodeProcess(sei.hProcess, ecode);
			PublishTest(st, *ecode, passed);
		}
	}
	delete ecode;
	fs.close();
}

int test() {
	//full_url = "http://my.test.server:882/some/path/script.php?parameters=123";
	//AfxParseURL(full_url, service, server, url, port);
	//ci = 1;
	if (getenv("APPVEYOR_PROJECT_NAME") != NULL) {
		ci = 1;
		//if (getenv("APPVEYOR_API_URL") != NULL) full_url = getenv("APPVEYOR_API_URL");
		//AfxParseURL(full_url, service, server, url, port);
	}
	logfile.open("autotest\\test.log", ios_base::app);

	TCHAR buffer[MAX_PATH];
	GetCurrentDirectory(MAX_PATH, buffer);
	current_dir = string(buffer).c_str();
	Log("Current dir: " + current_dir + "\n");

	LoadConfig();
	logfile.close();
	// Do not pause if continuous integration
	if (!ci) {
		cout << "Press any key to continue... ";
		_getch();
	}
	return 0;
}

int main()
{
    HMODULE hModule = ::GetModuleHandle(nullptr);

    if (hModule != nullptr)
    {
        // initialize MFC and print and error on failure
        if (!AfxWinInit(hModule, nullptr, ::GetCommandLine(), 0))
        {
            // TODO: change error code to suit your needs
            wprintf(L"Fatal Error: MFC initialization failed\n");
            nRetCode = 1;
        }
        else
        {
					test();
				}
    }
    else
    {
        // TODO: change error code to suit your needs
        wprintf(L"Fatal Error: GetModuleHandle failed\n");
        nRetCode = 1;
    }

    return nRetCode;
}
<|endoftext|>


<commit_before>// This is an independent project of an individual developer. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
// MGenTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "MGenTest.h"
#include "../MGen/GLibrary/GLib.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// The one and only application object

CWinApp theApp;

using namespace std;

CString current_dir;
ofstream logfile;
int continuous_integration = 0;
int nRetCode = 0;
int debug_level = 0;
vector<CString> errorMessages;
vector<CString> lyLogs;
vector<CString> lyConfigs;
CString pname;

// Default time to start aborting generation
int wait_sec = 60;
// Default time to consider generation timeout
int wait_sec2 = 120;

void InitErrorMessages() {
	errorMessages.resize(1000);
	errorMessages[0] = "OK";
	errorMessages[10] = "MGen detected critical errors during run";
	errorMessages[11] = "MGen generator freeze on exit - possible error in generator";
	errorMessages[100] = "GetExitCodeProcess error in MGenTest (for MGen.exe)";
	errorMessages[101] = "MGen process did not exit correctly - possible crash";
	errorMessages[102] = "GetExitCodeProcess error in MGenTest";
}

CString GetErrorMessage(int e) {
	if (e < errorMessages.size()) return errorMessages[e];
	else return "";
}

void Run(CString fname, CString par, int delay) {
	DWORD ecode;
	SHELLEXECUTEINFO sei = { 0 };
	sei.cbSize = sizeof(SHELLEXECUTEINFO);
	sei.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI;
	sei.hwnd = NULL;
	sei.lpVerb = NULL;
	sei.lpFile = fname;
	sei.lpParameters = par;
	sei.lpDirectory = NULL;
	sei.nShow = SW_SHOWNORMAL;
	sei.hInstApp = NULL;
	ShellExecuteEx(&sei);
	WaitForSingleObject(sei.hProcess, delay);
	if (!GetExitCodeProcess(sei.hProcess, &ecode)) ecode = 102;
	if (ecode != 0 && ecode != 259) {
		nRetCode = 3;
		cout << "Exit code " << ecode << ": " << fname << " " << par << "\n";
	}
}

void Log(CString st, int level = 0) {
	cout << st;
	logfile << st;
	if (continuous_integration && level > 0) {
		CString cat;
		if (level == 1) cat = "Information";
		if (level == 2) cat = "Warning";
		if (level == 3) cat = "Error";
		CString par = "AddMessage \"" + st + "\" -Category " + cat + " >> autotest\\run.log 2>&1";
		Run("appveyor", par, 1000);
	}
}

CString file(CString fname) {
	CString st, st2;
	ifstream fs;
	// Check file exists
	if (!CGLib::fileExists(fname)) {
		cout << "Not found file " << fname << "\n";
	}
	fs.open(fname);
	char pch[2550];
	while (fs.good()) {
		// Get line
		fs.getline(pch, 2550);
		st2 = pch;
		if (!st2.IsEmpty()) {
			st += "> " + st2 + "\n";
		}
	}
	fs.close();
	return st;
}

void ClearBuffer() {
	fstream fs;
	fs.open("autotest\\buffer.log", ios::out);
	fs.close();
	remove("autotest\\exit.log");
}

void PublishTest(CString tname, int result, int tpassed, CString params) {
	CString emes = GetErrorMessage(result);
	CString st;
	CString st2;
	st2.Format("%s: code %d (%s) in %d ms\n", tname, result, emes, tpassed);
	if (result) {
		nRetCode = 2;
		Log(st2, 3);
	}
	else {
		Log(st2, 1);
	}

	// Show errors
	CString errors = file("autotest/buffer.log");
	cout << errors;

	if (continuous_integration) {
		CString cat = "Passed";
		if (result) cat = "Failed";
		st.Format("UpdateTest \"%s\" -Framework MSTest -FileName MGen.exe -Duration %d -Outcome %s -ErrorMessage \"%d: %s\" >> autotest\\run.log 2>&1",
			tname, tpassed, cat, result, emes);
		Run("appveyor", st, 1000);
		// Send errors separately in case of command line overflow
		st.Format("UpdateTest \"%s\" -Framework MSTest -FileName MGen.exe -Duration %d -Outcome %s -ErrorMessage \"%d: %s\" -StdOut \"MGen.exe %s\" -ErrorStackTrace \"%s\" >> autotest\\run.log 2>&1",
			tname, tpassed, cat, result, emes, params, errors);
		Run("appveyor", st, 1000);
	}
}

void ParseLyLogs() {
	Sleep(1000);
	CString st;
	vector<CString> sv;
	int error;
	for (int i = 0; i < lyLogs.size(); ++i)
		if (CGLib::fileExists("autotest\\ly\\" + lyLogs[i] + ".log")) {
			// Send log
			if (continuous_integration && debug_level > 0) {
				CString suffix = "-release";
#ifdef _DEBUG
				suffix = "-debug";
#endif
				suffix += "-" + CTime::GetCurrentTime().Format("%Y-%m-%d_%H-%M-%S");
				Run("appveyor", "PushArtifact autotest\\ly\\" + lyLogs[i] +
					".log -Verbosity Normal -Type Auto -FileName " + lyLogs[i] +
					suffix + ".log >> run.log 2>&1", 1000);
			}
			CGLib::read_file_sv("autotest\\ly\\" + lyLogs[i] + ".log", sv);
			CString errors;
			for (int x = 0; x < sv.size(); ++x) {
				error = 0;
				if (sv[x].Find(" error: ") > -1) error = 1;
				if (sv[x].Find(" warning: ") > -1) error = 2;
				if (sv[x].Find("Exited with return code") > -1) error = 3;
				if (error) {
					if (errors.GetLength() < 1000) errors += "- " + sv[x] + "\n";
					CGLib::AppendLineToFile("autotest\\ly.log", lyLogs[i] + ": " + sv[x] + "\n");
				}
			}
			if (continuous_integration) {
				CString cat = "Passed";
				if (!errors.IsEmpty()) cat = "Failed";
				st.Format("AddTest \"LY: %s\" -Framework MSTest -FileName MGen.exe -Duration 0 -Outcome %s >> autotest\\run.log 2>&1",
					lyLogs[i], cat);
				Run("appveyor", st, 1000);
				// Send errors separately in case of command line overflow
				st.Format("AddTest \"LY: %s\" -Framework MSTest -FileName MGen.exe -Duration 0 -Outcome %s -ErrorStackTrace \"%s\" >> autotest\\run.log 2>&1",
					lyLogs[i], cat, errors);
				Run("appveyor", st, 1000);
			}
		}
}

void LoadConfig() {
	long long time_start, time_stop;
	vector<CString> ast;
	CString fname = "autotest\\test.csv";
	// Check file exists
	if (!CGLib::fileExists(fname)) {
		cout << "Not found file " << fname << "\n";
	}
	// Clear expect.log
	remove("autotest\\expect.log");
	remove("autotest\\sas-emu.log");
	remove("autotest\\cor-ack.log");
	remove("autotest\\perf.log");
	// Clear run.log
	fstream fs;
	fs.open("autotest\\ly.log", ios::out);
	fs.close();
	fs.open("autotest\\run.log", ios::out);
	fs.close();
	// Open file
	fs.open(fname);
	DWORD ecode;
	CString st, st2;
	char pch[2550];
	int pos = 0;
	int passed;
	while (fs.good()) {
		fs.getline(pch, 2550);
		st = pch;
		pos = st.Find("#");
		if (pos != -1) st = st.Left(pos);
		st.Trim();
		if (st.GetLength()) {
			CGLib::Tokenize(st, ast, ";");
			pname = ast[0];
			if (ast.size() > 1 && atoi(ast[1]) > 0) wait_sec = atoi(ast[1]);
			if (ast.size() > 2 && atoi(ast[2]) > 0) wait_sec2 = atoi(ast[2]);
			ClearBuffer();
			if (continuous_integration) Run("appveyor", "AddTest \"" + pname + "\" -Framework MSTest -FileName MGen.exe -Outcome Running >> autotest\\run.log 2>&1", 1000);
			// MGen.exe -test=5 configs\GenCA2\good-cp5.pl
			st2.Format("-test=%d %s", wait_sec, pname);
			Log("Starting test config: " + st2 + "\n");
			SHELLEXECUTEINFO sei = { 0 };
			sei.cbSize = sizeof(SHELLEXECUTEINFO);
			sei.fMask = SEE_MASK_NOCLOSEPROCESS;
			sei.hwnd = NULL;
			sei.lpVerb = NULL;
			sei.lpFile = "MGen.exe";
			sei.lpParameters = st2;
			sei.lpDirectory = NULL;
			sei.nShow = SW_SHOW;
			sei.hInstApp = NULL;
			time_start = CGLib::time();
			ShellExecuteEx(&sei);
			if (WaitForSingleObject(sei.hProcess, wait_sec2 * 1000) == WAIT_TIMEOUT) {
				Log(pname + ": Timeout waiting for process\n", 3);
				exit(1);
			}

			time_stop = CGLib::time();
			passed = time_stop - time_start;
			if (!GetExitCodeProcess(sei.hProcess, &ecode)) ecode = 100;
			if (!CGLib::fileExists("autotest\\exit.log")) ecode = 101;

			if (!ecode) {
				CString pname2 = pname;
				pname2.Replace("configs\\", "");
				pname2.Replace(".pl", "");
				pname2.Replace("\\", "-");
				lyConfigs.push_back(pname);
				lyLogs.push_back(pname2);
			}

			PublishTest(pname, ecode, passed, st2);
		}
	}
	ParseLyLogs();
	if (continuous_integration) {
		CString suffix = "-release";
#ifdef _DEBUG
		suffix = "-debug";
#endif
		suffix += "-" + CTime::GetCurrentTime().Format("%Y-%m-%d_%H-%M-%S");
		if (CGLib::fileExists("autotest\\expect.log"))
			Run("appveyor", "PushArtifact autotest\\expect.log -Verbosity Normal -Type Auto -FileName expect" +
				suffix + ".log >> run.log 2>&1", 1000);
		if (CGLib::fileExists("autotest\\sas-emu.log"))
			Run("appveyor", "PushArtifact autotest\\sas-emu.log -Verbosity Normal -Type Auto -FileName sas-emu" +
				suffix + ".log >> run.log 2>&1", 1000);
		if (CGLib::fileExists("autotest\\cor-ack.log"))
			Run("appveyor", "PushArtifact autotest\\cor-ack.log -Verbosity Normal -Type Auto -FileName cor-ack" +
				suffix + ".log >> run.log 2>&1", 1000);
		if (CGLib::fileExists("autotest\\ly.log"))
			Run("appveyor", "PushArtifact autotest\\ly.log -Verbosity Normal -Type Auto -FileName ly" +
				suffix + ".log >> run.log 2>&1", 1000);
		if (CGLib::fileExists("autotest\\perf.log"))
			Run("appveyor", "PushArtifact autotest\\perf.log -Verbosity Normal -Type Auto -FileName perf" +
				suffix + ".log >> run.log 2>&1", 1000);
		if (CGLib::fileExists("autotest\\run.log"))
			Run("appveyor", "PushArtifact autotest\\run.log -Verbosity Normal -Type Auto -FileName run" +
				suffix + ".log", 1000);
	}
	// Show run output
	//Run("cmd.exe", "/c echo Test >> autotest\\run.log", 1000);
	CString outs = file("autotest\\run.log");
	cout << "Run log:\n";
	cout << outs;
	/*
	// Show expect output
	outs = file("autotest\\expect.log");
	cout << "Expect log:\n";
	cout << outs;
	outs = file("autotest\\sas-emu.log");
	cout << "SAS emulator log:\n";
	cout << outs;
	outs = file("autotest\\cor-ack.log");
	cout << "Correction acknowledge log:\n";
	cout << outs;
	outs = file("autotest\\perf.log");
	cout << "Correction acknowledge log:\n";
	cout << outs;
	outs = file("autotest\\ly.log");
	cout << "Lilypond log:\n";
	cout << outs;
	*/

	fs.close();
}

int test() {
	if (getenv("APPVEYOR_PROJECT_NAME") != NULL) {
		continuous_integration = 1;
	}
	logfile.open("autotest\\test.log", ios_base::app);

	TCHAR buffer[MAX_PATH];
	GetCurrentDirectory(MAX_PATH, buffer);
	current_dir = string(buffer).c_str();
	Log("Current dir: " + current_dir + "\n");

	LoadConfig();
	logfile.close();
	// Do not pause if continuous integration
	if (!continuous_integration) {
		cout << "Press any key to continue... ";
		_getch();
	}
	return 0;
}

int main()
{
	InitErrorMessages();
	HMODULE hModule = ::GetModuleHandle(nullptr);

    if (hModule != nullptr)
    {
        // initialize MFC and print and error on failure
        if (!AfxWinInit(hModule, nullptr, ::GetCommandLine(), 0))
        {
            wprintf(L"Fatal Error: MFC initialization failed\n");
            nRetCode = 4;
        }
        else
        {
					test();
				}
    }
    else
    {
        wprintf(L"Fatal Error: GetModuleHandle failed\n");
        nRetCode = 1;
    }

    return nRetCode;
}
<commit_msg>MGenTest: Give an error if log file does not exist<commit_after>// This is an independent project of an individual developer. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
// MGenTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "MGenTest.h"
#include "../MGen/GLibrary/GLib.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// The one and only application object

CWinApp theApp;

using namespace std;

CString current_dir;
ofstream logfile;
int continuous_integration = 0;
int nRetCode = 0;
int debug_level = 0;
vector<CString> errorMessages;
vector<CString> lyLogs;
vector<CString> lyConfigs;
CString pname;

// Default time to start aborting generation
int wait_sec = 60;
// Default time to consider generation timeout
int wait_sec2 = 120;

void InitErrorMessages() {
	errorMessages.resize(1000);
	errorMessages[0] = "OK";
	errorMessages[10] = "MGen detected critical errors during run";
	errorMessages[11] = "MGen generator freeze on exit - possible error in generator";
	errorMessages[100] = "GetExitCodeProcess error in MGenTest (for MGen.exe)";
	errorMessages[101] = "MGen process did not exit correctly - possible crash";
	errorMessages[102] = "GetExitCodeProcess error in MGenTest";
}

CString GetErrorMessage(int e) {
	if (e < errorMessages.size()) return errorMessages[e];
	else return "";
}

void Run(CString fname, CString par, int delay) {
	DWORD ecode;
	SHELLEXECUTEINFO sei = { 0 };
	sei.cbSize = sizeof(SHELLEXECUTEINFO);
	sei.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI;
	sei.hwnd = NULL;
	sei.lpVerb = NULL;
	sei.lpFile = fname;
	sei.lpParameters = par;
	sei.lpDirectory = NULL;
	sei.nShow = SW_SHOWNORMAL;
	sei.hInstApp = NULL;
	ShellExecuteEx(&sei);
	WaitForSingleObject(sei.hProcess, delay);
	if (!GetExitCodeProcess(sei.hProcess, &ecode)) ecode = 102;
	if (ecode != 0 && ecode != 259) {
		nRetCode = 3;
		cout << "Exit code " << ecode << ": " << fname << " " << par << "\n";
	}
}

void Log(CString st, int level = 0) {
	cout << st;
	logfile << st;
	if (continuous_integration && level > 0) {
		CString cat;
		if (level == 1) cat = "Information";
		if (level == 2) cat = "Warning";
		if (level == 3) cat = "Error";
		CString par = "AddMessage \"" + st + "\" -Category " + cat + " >> autotest\\run.log 2>&1";
		Run("appveyor", par, 1000);
	}
}

CString file(CString fname) {
	CString st, st2;
	ifstream fs;
	// Check file exists
	if (!CGLib::fileExists(fname)) {
		cout << "Not found file " << fname << "\n";
	}
	fs.open(fname);
	char pch[2550];
	while (fs.good()) {
		// Get line
		fs.getline(pch, 2550);
		st2 = pch;
		if (!st2.IsEmpty()) {
			st += "> " + st2 + "\n";
		}
	}
	fs.close();
	return st;
}

void ClearBuffer() {
	fstream fs;
	fs.open("autotest\\buffer.log", ios::out);
	fs.close();
	remove("autotest\\exit.log");
}

void PublishTest(CString tname, int result, int tpassed, CString params) {
	CString emes = GetErrorMessage(result);
	CString st;
	CString st2;
	st2.Format("%s: code %d (%s) in %d ms\n", tname, result, emes, tpassed);
	if (result) {
		nRetCode = 2;
		Log(st2, 3);
	}
	else {
		Log(st2, 1);
	}

	// Show errors
	CString errors = file("autotest/buffer.log");
	cout << errors;

	if (continuous_integration) {
		CString cat = "Passed";
		if (result) cat = "Failed";
		st.Format("UpdateTest \"%s\" -Framework MSTest -FileName MGen.exe -Duration %d -Outcome %s -ErrorMessage \"%d: %s\" >> autotest\\run.log 2>&1",
			tname, tpassed, cat, result, emes);
		Run("appveyor", st, 1000);
		// Send errors separately in case of command line overflow
		st.Format("UpdateTest \"%s\" -Framework MSTest -FileName MGen.exe -Duration %d -Outcome %s -ErrorMessage \"%d: %s\" -StdOut \"MGen.exe %s\" -ErrorStackTrace \"%s\" >> autotest\\run.log 2>&1",
			tname, tpassed, cat, result, emes, params, errors);
		Run("appveyor", st, 1000);
	}
}

void ParseLyLogs() {
	Sleep(1000);
	CString st;
	vector<CString> sv;
	int error;
	for (int i = 0; i < lyLogs.size(); ++i)
		if (CGLib::fileExists("autotest\\ly\\" + lyLogs[i] + ".log")) {
			// Send log
			if (continuous_integration && debug_level > 0) {
				CString suffix = "-release";
#ifdef _DEBUG
				suffix = "-debug";
#endif
				suffix += "-" + CTime::GetCurrentTime().Format("%Y-%m-%d_%H-%M-%S");
				Run("appveyor", "PushArtifact autotest\\ly\\" + lyLogs[i] +
					".log -Verbosity Normal -Type Auto -FileName " + lyLogs[i] +
					suffix + ".log >> run.log 2>&1", 1000);
			}
			CGLib::read_file_sv("autotest\\ly\\" + lyLogs[i] + ".log", sv);
			CString errors;
			for (int x = 0; x < sv.size(); ++x) {
				error = 0;
				if (sv[x].Find(" error: ") > -1) error = 1;
				if (sv[x].Find(" warning: ") > -1) error = 2;
				if (sv[x].Find("Exited with return code") > -1) error = 3;
				if (error) {
					if (errors.GetLength() < 1000) errors += "- " + sv[x] + "\n";
					CGLib::AppendLineToFile("autotest\\ly.log", lyLogs[i] + ": " + sv[x] + "\n");
				}
			}
			if (continuous_integration) {
				CString cat = "Passed";
				if (!errors.IsEmpty()) cat = "Failed";
				st.Format("AddTest \"LY: %s\" -Framework MSTest -FileName MGen.exe -Duration 0 -Outcome %s >> autotest\\run.log 2>&1",
					lyLogs[i], cat);
				Run("appveyor", st, 1000);
				// Send errors separately in case of command line overflow
				st.Format("AddTest \"LY: %s\" -Framework MSTest -FileName MGen.exe -Duration 0 -Outcome %s -ErrorStackTrace \"%s\" >> autotest\\run.log 2>&1",
					lyLogs[i], cat, errors);
				Run("appveyor", st, 1000);
			}
		}
}

void LoadConfig() {
	long long time_start, time_stop;
	vector<CString> ast;
	CString fname = "autotest\\test.csv";
	// Check file exists
	if (!CGLib::fileExists(fname)) {
		cout << "Not found file " << fname << "\n";
	}
	// Clear expect.log
	remove("autotest\\expect.log");
	remove("autotest\\sas-emu.log");
	remove("autotest\\cor-ack.log");
	remove("autotest\\perf.log");
	// Clear run.log
	fstream fs;
	fs.open("autotest\\ly.log", ios::out);
	fs.close();
	fs.open("autotest\\run.log", ios::out);
	fs.close();
	// Open file
	fs.open(fname);
	DWORD ecode;
	CString st, st2;
	char pch[2550];
	int pos = 0;
	int passed;
	while (fs.good()) {
		fs.getline(pch, 2550);
		st = pch;
		pos = st.Find("#");
		if (pos != -1) st = st.Left(pos);
		st.Trim();
		if (st.GetLength()) {
			CGLib::Tokenize(st, ast, ";");
			pname = ast[0];
			if (ast.size() > 1 && atoi(ast[1]) > 0) wait_sec = atoi(ast[1]);
			if (ast.size() > 2 && atoi(ast[2]) > 0) wait_sec2 = atoi(ast[2]);
			ClearBuffer();
			if (continuous_integration) Run("appveyor", "AddTest \"" + pname + "\" -Framework MSTest -FileName MGen.exe -Outcome Running >> autotest\\run.log 2>&1", 1000);
			// MGen.exe -test=5 configs\GenCA2\good-cp5.pl
			st2.Format("-test=%d %s", wait_sec, pname);
			Log("Starting test config: " + st2 + "\n");
			SHELLEXECUTEINFO sei = { 0 };
			sei.cbSize = sizeof(SHELLEXECUTEINFO);
			sei.fMask = SEE_MASK_NOCLOSEPROCESS;
			sei.hwnd = NULL;
			sei.lpVerb = NULL;
			sei.lpFile = "MGen.exe";
			sei.lpParameters = st2;
			sei.lpDirectory = NULL;
			sei.nShow = SW_SHOW;
			sei.hInstApp = NULL;
			time_start = CGLib::time();
			ShellExecuteEx(&sei);
			if (WaitForSingleObject(sei.hProcess, wait_sec2 * 1000) == WAIT_TIMEOUT) {
				Log(pname + ": Timeout waiting for process\n", 3);
				exit(1);
			}

			time_stop = CGLib::time();
			passed = time_stop - time_start;
			if (!GetExitCodeProcess(sei.hProcess, &ecode)) ecode = 100;
			if (!CGLib::fileExists("autotest\\exit.log")) ecode = 101;

			if (!ecode) {
				CString pname2 = pname;
				pname2.Replace("configs\\", "");
				pname2.Replace(".pl", "");
				pname2.Replace("\\", "-");
				lyConfigs.push_back(pname);
				lyLogs.push_back(pname2);
			}

			PublishTest(pname, ecode, passed, st2);
		}
	}
	ParseLyLogs();
	if (continuous_integration) {
		CString suffix = "-release";
#ifdef _DEBUG
		suffix = "-debug";
#endif
		suffix += "-" + CTime::GetCurrentTime().Format("%Y-%m-%d_%H-%M-%S");
		//if (CGLib::fileExists("autotest\\expect.log"))
			Run("appveyor", "PushArtifact autotest\\expect.log -Verbosity Normal -Type Auto -FileName expect" +
				suffix + ".log >> run.log 2>&1", 1000);
		//if (CGLib::fileExists("autotest\\sas-emu.log"))
			Run("appveyor", "PushArtifact autotest\\sas-emu.log -Verbosity Normal -Type Auto -FileName sas-emu" +
				suffix + ".log >> run.log 2>&1", 1000);
		//if (CGLib::fileExists("autotest\\cor-ack.log"))
			Run("appveyor", "PushArtifact autotest\\cor-ack.log -Verbosity Normal -Type Auto -FileName cor-ack" +
				suffix + ".log >> run.log 2>&1", 1000);
		//if (CGLib::fileExists("autotest\\ly.log"))
			Run("appveyor", "PushArtifact autotest\\ly.log -Verbosity Normal -Type Auto -FileName ly" +
				suffix + ".log >> run.log 2>&1", 1000);
		//if (CGLib::fileExists("autotest\\perf.log"))
			Run("appveyor", "PushArtifact autotest\\perf.log -Verbosity Normal -Type Auto -FileName perf" +
				suffix + ".log >> run.log 2>&1", 1000);
		//if (CGLib::fileExists("autotest\\run.log"))
			Run("appveyor", "PushArtifact autotest\\run.log -Verbosity Normal -Type Auto -FileName run" +
				suffix + ".log", 1000);
	}
	// Show run output
	//Run("cmd.exe", "/c echo Test >> autotest\\run.log", 1000);
	CString outs = file("autotest\\run.log");
	cout << "Run log:\n";
	cout << outs;
	/*
	// Show expect output
	outs = file("autotest\\expect.log");
	cout << "Expect log:\n";
	cout << outs;
	outs = file("autotest\\sas-emu.log");
	cout << "SAS emulator log:\n";
	cout << outs;
	outs = file("autotest\\cor-ack.log");
	cout << "Correction acknowledge log:\n";
	cout << outs;
	outs = file("autotest\\perf.log");
	cout << "Correction acknowledge log:\n";
	cout << outs;
	outs = file("autotest\\ly.log");
	cout << "Lilypond log:\n";
	cout << outs;
	*/

	fs.close();
}

int test() {
	if (getenv("APPVEYOR_PROJECT_NAME") != NULL) {
		continuous_integration = 1;
	}
	logfile.open("autotest\\test.log", ios_base::app);

	TCHAR buffer[MAX_PATH];
	GetCurrentDirectory(MAX_PATH, buffer);
	current_dir = string(buffer).c_str();
	Log("Current dir: " + current_dir + "\n");

	LoadConfig();
	logfile.close();
	// Do not pause if continuous integration
	if (!continuous_integration) {
		cout << "Press any key to continue... ";
		_getch();
	}
	return 0;
}

int main()
{
	InitErrorMessages();
	HMODULE hModule = ::GetModuleHandle(nullptr);

    if (hModule != nullptr)
    {
        // initialize MFC and print and error on failure
        if (!AfxWinInit(hModule, nullptr, ::GetCommandLine(), 0))
        {
            wprintf(L"Fatal Error: MFC initialization failed\n");
            nRetCode = 4;
        }
        else
        {
					test();
				}
    }
    else
    {
        wprintf(L"Fatal Error: GetModuleHandle failed\n");
        nRetCode = 1;
    }

    return nRetCode;
}
<|endoftext|>


<commit_before>/******************************************************************************
* Copyright (c) 2011, Howard Butler <hobu.inc@gmail.com>
*
* 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 Hobu, Inc. or Flaxen Geo Consulting 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.
****************************************************************************/

#include <pdal/filters/ByteSwap.hpp>
#include <pdal/filters/Chipper.hpp>

#include <pdal/Schema.hpp>
#include <pdal/PointBuffer.hpp>
#include <pdal/Endian.hpp>
#include <iostream>

#ifdef PDAL_COMPILER_MSVC
#  pragma warning(disable: 4127)  // conditional expression is constant
#endif

using namespace pdal::filters::chipper;

namespace pdal
{
namespace filters
{

ByteSwap::ByteSwap(Stage& prevStage, const Options& options)
    : pdal::Filter(prevStage, options)
{
    return;
}

ByteSwap::ByteSwap(Stage& prevStage)
    : Filter(prevStage, Options::none())
{
    return;
}

void ByteSwap::initialize()
{
    Filter::initialize();

    const Stage& stage = getPrevStage();
    this->setNumPoints(stage.getNumPoints());
    this->setPointCountType(stage.getPointCountType());

    Schema& schema = this->getSchemaRef();

    schema::index_by_index const& dimensions = schema.getDimensions().get<schema::index>();

    std::vector<Dimension> new_dimensions;
    for (schema::index_by_index::const_iterator i = dimensions.begin(); i != dimensions.end(); ++i)
    {
        pdal::Dimension d(*i);
        pdal::EndianType t = i->getEndianness();
        if (t == Endian_Little)
        {
            d.setEndianness(Endian_Big);
        }
        else if (t == Endian_Big)
        {
            d.setEndianness(Endian_Little);
        }
        else
        {
            throw pdal_error("ByteSwapFilter can only swap big/little endian dimensions");
        }
        new_dimensions.push_back(d);
    }

    schema = Schema(new_dimensions);
    return;
}

Options ByteSwap::getDefaultOptions()
{
    Options options;
    return options;
}

boost::uint32_t ByteSwap::processBuffer(PointBuffer& dstData, const PointBuffer& srcData) const
{
    const Schema& dstSchema = dstData.getSchema();

    schema::index_by_index const& dstDims = dstSchema.getDimensions().get<schema::index>();

    dstData.setSpatialBounds(srcData.getSpatialBounds());
    dstData.copyPointsFast(0, 0, srcData, srcData.getNumPoints());

    dstData.setNumPoints(srcData.getNumPoints());

    for (boost::uint32_t i = 0; i != dstData.getNumPoints(); ++i)
    {
        boost::uint8_t* data = dstData.getData(i);
        std::size_t position = 0;
        for (boost::uint32_t n = 0; n < dstDims.size(); ++n)
        {
            const Dimension& d = dstSchema.getDimension(n);
            std::size_t size = d.getByteSize();

            boost::uint8_t* pos = data + position;
            SWAP_ENDIANNESS_N(*pos, size);
            position = position + size;
        }

    }

    return dstData.getNumPoints();
}

pdal::StageSequentialIterator* ByteSwap::createSequentialIterator(PointBuffer& buffer) const
{
    return new pdal::filters::iterators::sequential::ByteSwap(*this, buffer);
}

namespace iterators
{
namespace sequential
{

ByteSwap::ByteSwap(const pdal::filters::ByteSwap& filter, PointBuffer& buffer)
    : pdal::FilterSequentialIterator(filter, buffer)
    , m_swapFilter(filter)
{
    return;
}

boost::uint64_t ByteSwap::skipImpl(boost::uint64_t count)
{
    return naiveSkipImpl(count);
}

boost::uint32_t ByteSwap::readBufferImpl(PointBuffer& dstData)
{
    // The client has asked us for dstData.getCapacity() points.
    // We will read from our previous stage until we get that amount (or
    // until the previous stage runs out of points).

    boost::uint32_t numPointsNeeded = dstData.getCapacity();
    boost::uint32_t numPointsAchieved = 0;

    while (numPointsNeeded > 0)
    {
        // set up buffer to be filled by prev stage
        PointBuffer srcData(dstData.getSchema(), numPointsNeeded);

        // read from prev stage
        const boost::uint32_t numSrcPointsRead = getPrevIterator().read(srcData);
        assert(numSrcPointsRead == srcData.getNumPoints());
        assert(numSrcPointsRead <= numPointsNeeded);

        numPointsAchieved += numSrcPointsRead;

        // we got no data, and there is no more to get -- exit the loop
        if (numSrcPointsRead == 0) return numPointsAchieved;

        // copy points from src (prev stage) into dst (our stage),
        // based on the CropFilter's rules (i.e. its bounds)
        const boost::uint32_t numPointsProcessed = m_swapFilter.processBuffer(dstData, srcData);

        numPointsNeeded -= numPointsProcessed;

    }

    return numPointsAchieved;
}

bool ByteSwap::atEndImpl() const
{
    // we don't have a fixed point point --
    // we are at the end only when our source is at the end
    const StageSequentialIterator& iter = getPrevIterator();
    return iter.atEnd();
}

}
} // iterators::sequential

}
} // pdal::filters
<commit_msg>ByteSwap doesn't need chipper<commit_after>/******************************************************************************
* Copyright (c) 2011, Howard Butler <hobu.inc@gmail.com>
*
* 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 Hobu, Inc. or Flaxen Geo Consulting 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.
****************************************************************************/

#include <pdal/filters/ByteSwap.hpp>

#include <pdal/Schema.hpp>
#include <pdal/PointBuffer.hpp>
#include <pdal/Endian.hpp>
#include <iostream>

#ifdef PDAL_COMPILER_MSVC
#  pragma warning(disable: 4127)  // conditional expression is constant
#endif

namespace pdal
{
namespace filters
{

ByteSwap::ByteSwap(Stage& prevStage, const Options& options)
    : pdal::Filter(prevStage, options)
{
    return;
}

ByteSwap::ByteSwap(Stage& prevStage)
    : Filter(prevStage, Options::none())
{
    return;
}

void ByteSwap::initialize()
{
    Filter::initialize();

    const Stage& stage = getPrevStage();
    this->setNumPoints(stage.getNumPoints());
    this->setPointCountType(stage.getPointCountType());

    Schema& schema = this->getSchemaRef();

    schema::index_by_index const& dimensions = schema.getDimensions().get<schema::index>();

    std::vector<Dimension> new_dimensions;
    for (schema::index_by_index::const_iterator i = dimensions.begin(); i != dimensions.end(); ++i)
    {
        pdal::Dimension d(*i);
        pdal::EndianType t = i->getEndianness();
        if (t == Endian_Little)
        {
            d.setEndianness(Endian_Big);
        }
        else if (t == Endian_Big)
        {
            d.setEndianness(Endian_Little);
        }
        else
        {
            throw pdal_error("ByteSwapFilter can only swap big/little endian dimensions");
        }
        new_dimensions.push_back(d);
    }

    schema = Schema(new_dimensions);
    return;
}

Options ByteSwap::getDefaultOptions()
{
    Options options;
    return options;
}

boost::uint32_t ByteSwap::processBuffer(PointBuffer& dstData, const PointBuffer& srcData) const
{
    const Schema& dstSchema = dstData.getSchema();

    schema::index_by_index const& dstDims = dstSchema.getDimensions().get<schema::index>();

    dstData.setSpatialBounds(srcData.getSpatialBounds());
    dstData.copyPointsFast(0, 0, srcData, srcData.getNumPoints());

    dstData.setNumPoints(srcData.getNumPoints());

    for (boost::uint32_t i = 0; i != dstData.getNumPoints(); ++i)
    {
        boost::uint8_t* data = dstData.getData(i);
        std::size_t position = 0;
        for (boost::uint32_t n = 0; n < dstDims.size(); ++n)
        {
            const Dimension& d = dstSchema.getDimension(n);
            std::size_t size = d.getByteSize();

            boost::uint8_t* pos = data + position;
            SWAP_ENDIANNESS_N(*pos, size);
            position = position + size;
        }

    }

    return dstData.getNumPoints();
}

pdal::StageSequentialIterator* ByteSwap::createSequentialIterator(PointBuffer& buffer) const
{
    return new pdal::filters::iterators::sequential::ByteSwap(*this, buffer);
}

namespace iterators
{
namespace sequential
{

ByteSwap::ByteSwap(const pdal::filters::ByteSwap& filter, PointBuffer& buffer)
    : pdal::FilterSequentialIterator(filter, buffer)
    , m_swapFilter(filter)
{
    return;
}

boost::uint64_t ByteSwap::skipImpl(boost::uint64_t count)
{
    return naiveSkipImpl(count);
}

boost::uint32_t ByteSwap::readBufferImpl(PointBuffer& dstData)
{
    // The client has asked us for dstData.getCapacity() points.
    // We will read from our previous stage until we get that amount (or
    // until the previous stage runs out of points).

    boost::uint32_t numPointsNeeded = dstData.getCapacity();
    boost::uint32_t numPointsAchieved = 0;

    while (numPointsNeeded > 0)
    {
        // set up buffer to be filled by prev stage
        PointBuffer srcData(dstData.getSchema(), numPointsNeeded);

        // read from prev stage
        const boost::uint32_t numSrcPointsRead = getPrevIterator().read(srcData);
        assert(numSrcPointsRead == srcData.getNumPoints());
        assert(numSrcPointsRead <= numPointsNeeded);

        numPointsAchieved += numSrcPointsRead;

        // we got no data, and there is no more to get -- exit the loop
        if (numSrcPointsRead == 0) return numPointsAchieved;

        // copy points from src (prev stage) into dst (our stage),
        // based on the CropFilter's rules (i.e. its bounds)
        const boost::uint32_t numPointsProcessed = m_swapFilter.processBuffer(dstData, srcData);

        numPointsNeeded -= numPointsProcessed;

    }

    return numPointsAchieved;
}

bool ByteSwap::atEndImpl() const
{
    // we don't have a fixed point point --
    // we are at the end only when our source is at the end
    const StageSequentialIterator& iter = getPrevIterator();
    return iter.atEnd();
}

}
} // iterators::sequential

}
} // pdal::filters
<|endoftext|>


<commit_before>#include "world.hpp"
#include "entity.hpp"
#include "thinker.hpp"
#include "stars.hpp"
#include "opengl.hpp"
#include "player.hpp"
#include "graphics/video.hpp"
namespace Space {

struct World::Event {
    enum Type {
        EntityAdd,
        EntityRemove,
        ThinkerAdd,
        ThinkerRemove
    };

    Type t;
    void *o;

    Event(Type tt, Entity *oo)
        : t(tt), o(reinterpret_cast<void*>(oo))
    { }

    Event(Type tt, Thinker *oo)
        : t(tt), o(reinterpret_cast<void*>(oo))
    { }

    Entity *asEntity() const
    {
        return reinterpret_cast<Entity*>(o);
    }

    Thinker *asThinker() const
    {
        return reinterpret_cast<Thinker *>(o);
    }
};

World::World()
  : time_(0.0)
{
    starfields_.reserve(9);
    for (int i = 0; i < 9; ++i) {
        starfields_.push_back(Starfield());
        starfields_[i].parallax = 0.1 * (i + 1);
        starfields_[i].tileSize = 64.0;
    }
}

World::~World()
{
    for (std::set<Entity*>::iterator
             i = entities_.begin(), e = entities_.end();
         i != e; ++i)
        delete *i;
    for (std::set<Thinker*>::iterator
             i = thinkers_.begin(), e = thinkers_.end();
         i != e; ++i)
        delete *i;
}

void World::update(unsigned ticks)
{
    double new_time = 0.001 * ticks;
    double delta = new_time - time_;
    time_ = new_time;

    for (unsigned int i = 0; i < events_.size(); ++i) {
        Event evt = events_[i];
        Entity *e;
        Thinker *t;

        switch (evt.t) {
        case Event::EntityAdd:
            e = evt.asEntity();
            entities_.insert(e);
            break;

        case Event::EntityRemove:
            e = evt.asEntity();
            if (entities_.erase(e))
                delete e;
            break;

        case Event::ThinkerAdd:
            t = evt.asThinker();
            thinkers_.insert(t);
            t->enterGame(*this);
            break;

        case Event::ThinkerRemove:
            t = evt.asThinker();
            if (thinkers_.erase(t)) {
                t->leaveGame(*this);
                delete t;
            }
            break;
        }
    }
    events_.clear();

    for (std::set<Thinker *>::iterator
             i = thinkers_.begin(),
             e = thinkers_.end();
         i != e; ++i) {
        Thinker &a = **i;
        a.think(*this, delta);
    }

    for (std::set<Entity*>::iterator
             i = entities_.begin(),
             e = entities_.end();
         i != e; ++i) {
        Entity &a = **i;
        a.move(*this, delta);
    }
}

void World::draw()
{
    int w = Video::width, h = Video::height;
    glClear(GL_COLOR_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-w/2, w-w/2, -h/2, h-h/2, -1.0, 1.0);
    glMatrixMode(GL_MODELVIEW);

    vector loc = player_->location();
    glLoadIdentity();
    glTranslatef(-loc.v[0], -loc.v[1], 0.0f);

    for (std::vector<Starfield>::iterator
             i = starfields_.begin(), e = starfields_.end();
         i != e; ++i)
        i->draw(loc.v[0] - w/2, loc.v[1] - h/2, w, h);

    for (std::set<Entity*>::iterator
             i = entities_.begin(),
             e = entities_.end();
         i != e; ++i)
        (*i)->draw();
}

void World::addEntity(Entity *e)
{
    events_.push_back(Event(Event::EntityAdd, e));
}

void World::removeEntity(Entity *e)
{
    events_.push_back(Event(Event::EntityRemove, e));
}

void World::addThinker(Thinker* t)
{
    events_.push_back(Event(Event::ThinkerAdd, t));
}

void World::removeThinker(Thinker* t)
{
    events_.push_back(Event(Event::ThinkerRemove, t));
}

}
<commit_msg>Fix whitespace<commit_after>#include "world.hpp"
#include "entity.hpp"
#include "thinker.hpp"
#include "stars.hpp"
#include "opengl.hpp"
#include "player.hpp"
#include "graphics/video.hpp"
namespace Space {

struct World::Event {
    enum Type {
        EntityAdd,
        EntityRemove,
        ThinkerAdd,
        ThinkerRemove
    };

    Type t;
    void *o;

    Event(Type tt, Entity *oo)
        : t(tt), o(reinterpret_cast<void*>(oo))
    { }

    Event(Type tt, Thinker *oo)
        : t(tt), o(reinterpret_cast<void*>(oo))
    { }

    Entity *asEntity() const
    {
        return reinterpret_cast<Entity*>(o);
    }

    Thinker *asThinker() const
    {
        return reinterpret_cast<Thinker *>(o);
    }
};

World::World()
    : time_(0.0)
{
    starfields_.reserve(9);
    for (int i = 0; i < 9; ++i) {
        starfields_.push_back(Starfield());
        starfields_[i].parallax = 0.1 * (i + 1);
        starfields_[i].tileSize = 64.0;
    }
}

World::~World()
{
    for (std::set<Entity*>::iterator
             i = entities_.begin(), e = entities_.end();
         i != e; ++i)
        delete *i;
    for (std::set<Thinker*>::iterator
             i = thinkers_.begin(), e = thinkers_.end();
         i != e; ++i)
        delete *i;
}

void World::update(unsigned ticks)
{
    double new_time = 0.001 * ticks;
    double delta = new_time - time_;
    time_ = new_time;

    for (unsigned int i = 0; i < events_.size(); ++i) {
        Event evt = events_[i];
        Entity *e;
        Thinker *t;

        switch (evt.t) {
        case Event::EntityAdd:
            e = evt.asEntity();
            entities_.insert(e);
            break;

        case Event::EntityRemove:
            e = evt.asEntity();
            if (entities_.erase(e))
                delete e;
            break;

        case Event::ThinkerAdd:
            t = evt.asThinker();
            thinkers_.insert(t);
            t->enterGame(*this);
            break;

        case Event::ThinkerRemove:
            t = evt.asThinker();
            if (thinkers_.erase(t)) {
                t->leaveGame(*this);
                delete t;
            }
            break;
        }
    }
    events_.clear();

    for (std::set<Thinker *>::iterator
             i = thinkers_.begin(),
             e = thinkers_.end();
         i != e; ++i) {
        Thinker &a = **i;
        a.think(*this, delta);
    }

    for (std::set<Entity*>::iterator
             i = entities_.begin(),
             e = entities_.end();
         i != e; ++i) {
        Entity &a = **i;
        a.move(*this, delta);
    }
}

void World::draw()
{
    int w = Video::width, h = Video::height;
    glClear(GL_COLOR_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-w/2, w-w/2, -h/2, h-h/2, -1.0, 1.0);
    glMatrixMode(GL_MODELVIEW);

    vector loc = player_->location();
    glLoadIdentity();
    glTranslatef(-loc.v[0], -loc.v[1], 0.0f);

    for (std::vector<Starfield>::iterator
             i = starfields_.begin(), e = starfields_.end();
         i != e; ++i)
        i->draw(loc.v[0] - w/2, loc.v[1] - h/2, w, h);

    for (std::set<Entity*>::iterator
             i = entities_.begin(),
             e = entities_.end();
         i != e; ++i)
        (*i)->draw();
}

void World::addEntity(Entity *e)
{
    events_.push_back(Event(Event::EntityAdd, e));
}

void World::removeEntity(Entity *e)
{
    events_.push_back(Event(Event::EntityRemove, e));
}

void World::addThinker(Thinker* t)
{
    events_.push_back(Event(Event::ThinkerAdd, t));
}

void World::removeThinker(Thinker* t)
{
    events_.push_back(Event(Event::ThinkerRemove, t));
}

}
<|endoftext|>


<commit_before>/// @file
/// @author uentity
/// @date 15.04.2020
/// @brief Fusion link actor impl
/// @copyright
/// 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 https://mozilla.org/MPL/2.0/

#include "fusion_link_actor.h"
#include "request_impl.h"

#include <bs/kernel/types_factory.h>

NAMESPACE_BEGIN(blue_sky::tree)
using namespace allow_enumops;
using bs_detail::shared;

/*-----------------------------------------------------------------------------
 *  fusion_link impl
 *-----------------------------------------------------------------------------*/
fusion_link_impl::fusion_link_impl(std::string name, sp_obj data, sp_fusion bridge, Flags f) :
	super(std::move(name), data, f), bridge_(std::move(bridge)), data_(std::move(data))
{}

fusion_link_impl::fusion_link_impl() :
	super()
{}

auto fusion_link_impl::spawn_actor(std::shared_ptr<link_impl> limpl) const -> caf::actor {
	return spawn_lactor<fusion_link_actor>(std::move(limpl));
}

auto fusion_link_impl::clone(bool deep) const -> sp_limpl {
	return std::make_shared<fusion_link_impl>(
		name_,
		deep ? kernel::tfactory::clone_object(data_) : data_,
		bridge_, flags_
	);
}

// search for valid (non-null) bridge up the tree
auto fusion_link_impl::bridge() const -> sp_fusion {
	if(bridge_) return bridge_;
	// try to look up in parent link
	if(auto parent = owner()) {
		if(auto phandle = fusion_link{ parent.handle() })
			return phandle.bridge();
	}
	return nullptr;
}

auto fusion_link_impl::reset_bridge(sp_fusion&& new_bridge) -> void {
	bridge_ = std::move(new_bridge);
}

// request data via bridge
auto fusion_link_impl::data() -> obj_or_err {
	if(req_status(Req::Data) == ReqStatus::OK)
		return data_;
	if(const auto B = bridge()) {
		if(!data_) data_ = std::make_shared<objnode>();
		auto err = B->pull_data(data_, super_engine());
		if(err.code == obj_fully_loaded)
			rs_reset(Req::DataNode, ReqReset::IfNeq, ReqStatus::OK, ReqStatus::Busy);
		return err.ok() ? obj_or_err(data_) : tl::make_unexpected(std::move(err));
	}
	return unexpected_err(Error::NoFusionBridge);
}

// unsafe version returns cached value
auto fusion_link_impl::data(unsafe_t) -> sp_obj {
	return data_;
}

// populate with specified child type
auto fusion_link_impl::populate(const std::string& child_type_id) -> node_or_err {
	// assume that if `child_type_id` is nonepmty,
	// then we should force `populate()` regardless of status
	if(child_type_id.empty() && req_status(Req::DataNode) == ReqStatus::OK)
		return data_->data_node();
	if(const auto B = bridge()) {
		if(!data_) data_ = std::make_shared<objnode>();
		auto err = B->populate(data_, super_engine(), child_type_id);
		if(err.code == obj_fully_loaded)
			rs_reset(Req::Data, ReqReset::IfNeq, ReqStatus::OK, ReqStatus::Busy);
		return err.ok() ?
			node_or_err(data_->data_node()) : tl::make_unexpected(std::move(err));
	}
	return unexpected_err(Error::NoFusionBridge);
}

/*-----------------------------------------------------------------------------
 *  fusion_link actor
 *-----------------------------------------------------------------------------*/
// both Data & DataNode execute with `HasDataCache` flag set
auto fusion_link_actor::data_ex(obj_processor_f cb, ReqOpts opts) -> void {
	request_impl(
		*this, Req::Data, opts | ReqOpts::HasDataCache | ReqOpts::Detached,
		[Limpl = pimpl_] { return static_cast<fusion_link_impl&>(*Limpl).data(); },
		std::move(cb)
	);
}

// `data_node` just calls `populate`
auto fusion_link_actor::data_node_ex(node_processor_f cb, ReqOpts opts) -> void {
	request_impl(
		*this, Req::DataNode, opts | ReqOpts::HasDataCache | ReqOpts::Detached,
		[Limpl = pimpl_] { return static_cast<fusion_link_impl&>(*Limpl).populate(); },
		std::move(cb)
	);
}

auto fusion_link_actor::make_typed_behavior() -> typed_behavior {
	return first_then_second(typed_behavior_overload{
		// add handler to invoke populate with specified child type
		[=](a_flnk_populate, std::string child_type_id, bool wait_if_busy) -> caf::result<node_or_errbox> {
			auto res = make_response_promise<node_or_errbox>();
			request_impl(
				*this, Req::DataNode,
				ReqOpts::Detached | ReqOpts::HasDataCache |
					(wait_if_busy ? ReqOpts::WaitIfBusy : ReqOpts::ErrorIfBusy),
				[Limpl = pimpl_, ctid = std::move(child_type_id)] {
					return static_cast<fusion_link_impl&>(*Limpl).populate(ctid);
				},
				[=](node_or_errbox N) mutable { res.deliver(std::move(N)); }
			);
			return res;
		},

		// [NOTE] idea is to delegate delivery to parent actor instead of calling
		[=](a_flnk_bridge) -> caf::result<sp_fusion> {
			if(fimpl().bridge_) return fimpl().bridge_;
			// try to look up in parent link
			if(auto parent = impl.owner()) {
				if(auto phandle = fusion_link{ parent.handle() })
					return delegate(link::actor(phandle), a_flnk_bridge());
			}
			return nullptr;
		},

		[=](a_flnk_bridge, sp_fusion new_bridge) { fimpl().reset_bridge(std::move(new_bridge)); },

		// easier obj ID & object type id retrival
		[=](a_lnk_otid) {
			return impl.data_ ? impl.data_->type_id() : nil_otid;
		},
		[=](a_lnk_oid) {
			return impl.data_ ? impl.data_->id() : nil_oid;
		}
	}, super::make_typed_behavior());
}

auto fusion_link_actor::make_behavior() -> behavior_type {
	return make_typed_behavior().unbox();
}

NAMESPACE_END(blue_sky::tree)
<commit_msg>tree/fusion_link: minor refactor<commit_after>/// @file
/// @author uentity
/// @date 15.04.2020
/// @brief Fusion link actor impl
/// @copyright
/// 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 https://mozilla.org/MPL/2.0/

#include "fusion_link_actor.h"
#include "request_impl.h"

#include <bs/kernel/types_factory.h>

NAMESPACE_BEGIN(blue_sky::tree)
using namespace allow_enumops;
using bs_detail::shared;

/*-----------------------------------------------------------------------------
 *  fusion_link impl
 *-----------------------------------------------------------------------------*/
fusion_link_impl::fusion_link_impl(std::string name, sp_obj data, sp_fusion bridge, Flags f) :
	super(std::move(name), data, f), bridge_(std::move(bridge)),
	data_(data ? std::move(data) : std::make_shared<objnode>())
{}

fusion_link_impl::fusion_link_impl() :
	super(), data_(std::make_shared<objnode>())
{}

auto fusion_link_impl::spawn_actor(std::shared_ptr<link_impl> limpl) const -> caf::actor {
	return spawn_lactor<fusion_link_actor>(std::move(limpl));
}

auto fusion_link_impl::clone(bool deep) const -> sp_limpl {
	return std::make_shared<fusion_link_impl>(
		name_,
		deep ? kernel::tfactory::clone_object(data_) : data_,
		bridge_, flags_
	);
}

// search for valid (non-null) bridge up the tree
auto fusion_link_impl::bridge() const -> sp_fusion {
	if(bridge_) return bridge_;
	// try to look up in parent link
	if(auto parent = owner()) {
		if(auto phandle = fusion_link{ parent.handle() })
			return phandle.bridge();
	}
	return nullptr;
}

auto fusion_link_impl::reset_bridge(sp_fusion&& new_bridge) -> void {
	bridge_ = std::move(new_bridge);
}

// request data via bridge
auto fusion_link_impl::data() -> obj_or_err {
	if(req_status(Req::Data) != ReqStatus::OK) {
		const auto B = bridge();
		if(!B) return unexpected_err(Error::NoFusionBridge);

		auto err = B->pull_data(data_, super_engine());
		if(err.code == obj_fully_loaded)
			rs_reset(Req::DataNode, ReqReset::IfNeq, ReqStatus::OK, ReqStatus::Busy);
		else if(err)
			return tl::make_unexpected(std::move(err));
	}
	return data_;
}

// unsafe version returns cached value
auto fusion_link_impl::data(unsafe_t) -> sp_obj {
	return data_;
}

// populate with specified child type
auto fusion_link_impl::populate(const std::string& child_type_id) -> node_or_err {
	// assume that if `child_type_id` is nonepmty,
	// then we should force `populate()` regardless of status
	if(req_status(Req::Data) != ReqStatus::OK || child_type_id.empty()) {
		const auto B = bridge();
		if(!B) return unexpected_err(Error::NoFusionBridge);

		auto err = B->populate(data_, super_engine(), child_type_id);
		if(err.code == obj_fully_loaded)
			rs_reset(Req::Data, ReqReset::IfNeq, ReqStatus::OK, ReqStatus::Busy);
		else if(err)
			return tl::make_unexpected(std::move(err));
	}
	return data_->data_node();
}

/*-----------------------------------------------------------------------------
 *  fusion_link actor
 *-----------------------------------------------------------------------------*/
// both Data & DataNode execute with `HasDataCache` flag set
auto fusion_link_actor::data_ex(obj_processor_f cb, ReqOpts opts) -> void {
	request_impl(
		*this, Req::Data, opts | ReqOpts::HasDataCache | ReqOpts::Detached,
		[Limpl = pimpl_] { return static_cast<fusion_link_impl&>(*Limpl).data(); },
		std::move(cb)
	);
}

// `data_node` just calls `populate`
auto fusion_link_actor::data_node_ex(node_processor_f cb, ReqOpts opts) -> void {
	request_impl(
		*this, Req::DataNode, opts | ReqOpts::HasDataCache | ReqOpts::Detached,
		[Limpl = pimpl_] { return static_cast<fusion_link_impl&>(*Limpl).populate(); },
		std::move(cb)
	);
}

auto fusion_link_actor::make_typed_behavior() -> typed_behavior {
	return first_then_second(typed_behavior_overload{
		// add handler to invoke populate with specified child type
		[=](a_flnk_populate, std::string child_type_id, bool wait_if_busy) -> caf::result<node_or_errbox> {
			auto res = make_response_promise<node_or_errbox>();
			request_impl(
				*this, Req::DataNode,
				ReqOpts::Detached | ReqOpts::HasDataCache |
					(wait_if_busy ? ReqOpts::WaitIfBusy : ReqOpts::ErrorIfBusy),
				[Limpl = pimpl_, ctid = std::move(child_type_id)] {
					return static_cast<fusion_link_impl&>(*Limpl).populate(ctid);
				},
				[=](node_or_errbox N) mutable { res.deliver(std::move(N)); }
			);
			return res;
		},

		// [NOTE] idea is to delegate delivery to parent actor instead of calling
		[=](a_flnk_bridge) -> caf::result<sp_fusion> {
			if(fimpl().bridge_) return fimpl().bridge_;
			// try to look up in parent link
			if(auto parent = impl.owner()) {
				if(auto phandle = fusion_link{ parent.handle() })
					return delegate(link::actor(phandle), a_flnk_bridge());
			}
			return nullptr;
		},

		[=](a_flnk_bridge, sp_fusion new_bridge) { fimpl().reset_bridge(std::move(new_bridge)); },

		// easier obj ID & object type id retrival
		[=](a_lnk_otid) {
			return impl.data_ ? impl.data_->type_id() : nil_otid;
		},
		[=](a_lnk_oid) {
			return impl.data_ ? impl.data_->id() : nil_oid;
		}
	}, super::make_typed_behavior());
}

auto fusion_link_actor::make_behavior() -> behavior_type {
	return make_typed_behavior().unbox();
}

NAMESPACE_END(blue_sky::tree)
<|endoftext|>


<commit_before>/* This file is part of the KDE libraries
   Copyright (C) 2003-2005 Hamish Rodda <rodda@kde.org>
   Copyright (C) 2002 Christian Couder <christian@kdevelop.org>
   Copyright (C) 2001, 2003 Christoph Cullmann <cullmann@kde.org>
   Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
   Copyright (C) 1999 Jochen Wilhelmy <digisnap@cs.tu-berlin.de>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License version 2 as published by the Free Software Foundation.

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

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.
*/

#include "range.h"

#include "document.h"
#include "view.h"
#include "attribute.h"

#include <kaction.h>

using namespace KTextEditor;

Range::Range()
  : m_start(new Cursor())
  , m_end(new Cursor())
{
}

Range::Range(const Cursor& start, const Cursor& end)
  : m_start(new Cursor(start))
  , m_end(new Cursor(end))
{
}

Range::Range(const Cursor& start, int width)
  : m_start(new Cursor(start))
  , m_end(new Cursor(start.line(), start.column() + width))
{
}

Range::Range(const Cursor& start, int endLine, int endCol)
  : m_start(new Cursor(start))
  , m_end(new Cursor(endLine, endCol))
{
}

Range::Range(int startLine, int startCol, int endLine, int endCol)
  : m_start(new Cursor(startLine, startCol))
  , m_end(new Cursor(endLine, endCol))
{
}

Range::Range(Cursor* start, Cursor* end)
  : m_start(start)
  , m_end(end)
{
}

Range::Range(const Range& copy)
  : m_start(new Cursor(copy.start()))
  , m_end(new Cursor(copy.end()))
{
}

Range::~Range()
{
  delete m_start;
  delete m_end;
}

Range& Range::operator= (const Range& rhs)
{
  if (this == &rhs)
    return;

  setRange(rhs);

  return *this;
}

void Range::setStart(const Cursor& newStart)
{
  *m_start = newStart;
  if (start() > end())
    *m_end = newStart;
}

void Range::setEnd(const Cursor& newEnd)
{
  *m_end = newEnd;
  if (start() > end())
    *m_start = newEnd;
}

void Range::setRange(const Range& range)
{
  *m_start = range.start();
  *m_end = range.end();
}

void Range::setRange( const Cursor & start, const Cursor & end )
{
  if (start > end) {
    *m_start = end;
    *m_end = start;
  } else {
    *m_start = start;
    *m_end = end;
  }
}

bool Range::containsLine(int line) const
{
  return (line > start().line() || line == start().line() && !start().column()) && line < end().line();
}

bool Range::includesLine(int line) const
{
  return line >= start().line() && line <= end().line();
}

bool Range::spansColumn( int col ) const
{
  return start().column() <= col && end().column() > col;
}

bool Range::contains( const Cursor& cursor ) const
{
  return cursor >= start() && cursor < end();
}

bool Range::contains( const Range& range ) const
{
  return range.start() >= start() && range.end() <= end();
}

bool Range::overlaps( const Range& range ) const
{
  if (range.start() <= start())
    return range.end() > start();

  else if (range.end() >= end())
    return range.start() < end();

  else
    return contains(range);
}

bool Range::boundaryAt(const KTextEditor::Cursor& cursor) const
{
  return cursor == start() || cursor == end();
}

bool Range::boundaryOnLine(int line) const
{
  return start().line() == line || end().line() == line;
}

void Range::confineToRange(const Range& range)
{
  if (start() < range.start())
    if (end() < range.end())
      setRange(range);
    else
      setStart(range.start());
  else if (end() < range.end())
    setEnd(range.end());
}

void SmartRange::confineToRange(const Range& range)
{
  if (start() < range.start())
    if (end() < range.end())
      setRange(range);
    else
      setStart(range.start());
  else if (end() < range.end())
    setEnd(range.end());
  else
    // Don't need to check if children should be confined, they already are
    return;

  foreach (SmartRange* child, m_childRanges)
    child->confineToRange(*this);
}

SmartRange::SmartRange(SmartCursor* start, SmartCursor* end, SmartRange * parent, int insertBehaviour )
  : Range(start, end)
  , m_attribute(0L)
  , m_parentRange(parent)
  , m_insertBehaviour(insertBehaviour)
  , m_ownsAttribute(false)
{
  start->setBelongsToRange(this);
  end->setBelongsToRange(this);
}

SmartRange * SmartRange::childBefore( const SmartRange * range ) const
{
  int index = m_childRanges.indexOf(const_cast<SmartRange*>(range));
  if (index != -1 && --index > 0)
    return m_childRanges[index];
  return 0L;
}

SmartRange * SmartRange::childAfter( const SmartRange * range ) const
{
  int index = m_childRanges.indexOf(const_cast<SmartRange*>(range));
  if (index != -1 && ++index < m_childRanges.count())
    return m_childRanges[index];
  return 0L;
}

void SmartRange::setAttribute( Attribute * attribute, bool ownsAttribute )
{
  if (m_ownsAttribute)
      delete m_attribute;
  m_attribute = attribute;
  m_ownsAttribute = ownsAttribute;
}

SmartRange::~SmartRange( )
{
  if (m_ownsAttribute)
    delete m_attribute;

  /*if (!m_deleteCursors)
  {
    // Save from deletion in the parent
    m_start = 0L;
    m_end = 0L;
  }*/
}

SmartRange * KTextEditor::SmartRange::findMostSpecificRange( const Range & input ) const
{
  if (contains(input)) {
    for (QList<SmartRange*>::ConstIterator it = m_childRanges.constBegin(); it != m_childRanges.constEnd(); ++it)
      if ((*it)->contains(input))
        return (*it)->findMostSpecificRange(input);

    return const_cast<SmartRange*>(this);

  } else if (parentRange()) {
    return parentRange()->findMostSpecificRange(input);

  } else {
    return 0L;
  }
}

SmartRange * KTextEditor::SmartRange::firstRangeIncluding( const Cursor & pos ) const
{
  switch (relativePosition(pos)) {
    case 0:
      if (parentRange() && parentRange()->contains(pos))
        return parentRange()->firstRangeIncluding(pos);

      return const_cast<SmartRange*>(this);

    case -1:
      if (!parentRange())
        return 0L;

      if (!parentRange()->contains(pos))
        return parentRange()->firstRangeIncluding(pos);

      if (SmartRange* r = parentRange()->childAfter(this))
        return r->firstRangeIncluding(pos);

      return 0L;

    case 1:
      if (!parentRange())
        return 0L;

      if (!parentRange()->contains(pos))
        return parentRange()->firstRangeIncluding(pos);

      if (const SmartRange* r = parentRange()->childBefore(this))
        return r->firstRangeIncluding(pos);

      return 0L;

    default:
      Q_ASSERT(false);
      return 0L;
  }
}

SmartRange * KTextEditor::SmartRange::deepestRangeContaining( const Cursor & pos ) const
{
  switch (relativePosition(pos)) {
    case 0:
      for (QList<SmartRange*>::ConstIterator it = m_childRanges.constBegin(); it != m_childRanges.constEnd(); ++it)
        if ((*it)->contains(pos) == 0)
          return ((*it)->deepestRangeContaining(pos));

      return const_cast<SmartRange*>(this);

    case -1:
      if (!parentRange())
        return 0L;

      if (!parentRange()->contains(pos))
        return parentRange()->deepestRangeContaining(pos);

      if (const SmartRange* r = parentRange()->childAfter(this))
        return r->deepestRangeContaining(pos);

      return 0L;

    case 1:
      if (!parentRange())
        return 0L;

      if (!parentRange()->contains(pos))
        return parentRange()->deepestRangeContaining(pos);

      if (const SmartRange* r = parentRange()->childBefore(this))
        return r->firstRangeIncluding(pos);

      return 0L;

    default:
      Q_ASSERT(false);
      return 0L;
  }
}

Document* SmartRange::document( ) const
{
  return smartStart().document();
}

void SmartRange::attachAction( KAction * action )
{
  m_associatedActions.append(action);

  bool enable = false;
  if (View* v = document()->activeView())
    if (contains(v->cursorPosition()))
      enable = true;

  action->setEnabled(enable);

  if (m_associatedActions.count() == 1)
    checkFeedback();
}

void SmartRange::detachAction( KAction * action )
{
  m_associatedActions.remove(action);
  if (!m_associatedActions.count())
    checkFeedback();
}

int SmartRange::insertBehaviour( ) const
{
  return (smartStart().moveOnInsert() ? DoNotExpand : ExpandLeft) | (smartEnd().moveOnInsert() ? ExpandRight : DoNotExpand);
}

void SmartRange::setInsertBehaviour(int behaviour)
{
  static_cast<SmartCursor*>(m_start)->setMoveOnInsert(behaviour & ExpandLeft);
  static_cast<SmartCursor*>(m_end)->setMoveOnInsert(!(behaviour & ExpandRight));
}

void SmartRange::clearAllChildRanges()
{
  while (m_childRanges.count()) {
    KTextEditor::Range* r = m_childRanges.first();
    m_childRanges.remove(m_childRanges.begin());

    delete r;
  }
}

void SmartRange::deleteAllChildRanges()
{
  while (m_childRanges.count()) {
    KTextEditor::Range* r = m_childRanges.first();
    m_childRanges.remove(m_childRanges.begin());

    // FIXME editDeleteText here? or a call to delete the text on the range object
    delete r;
  }
}

const Range& Range::invalid()
{
  static Range r;
  if (r.start().line() != -1)
    r.setRange(Cursor(-1,-1),Cursor(-1,-1));
  return r;
}

KTextEditor::SmartRangeWatcher::~ SmartRangeWatcher( )
{
}

void KTextEditor::SmartRangeWatcher::positionChanged( SmartRange * )
{
}

void KTextEditor::SmartRangeWatcher::contentsChanged( SmartRange * )
{
}

void KTextEditor::SmartRangeWatcher::boundaryDeleted( SmartRange * , bool )
{
}

void KTextEditor::SmartRangeWatcher::eliminated( SmartRange * )
{
}

void KTextEditor::SmartRangeWatcher::firstCharacterDeleted( SmartRange * )
{
}

void KTextEditor::SmartRangeWatcher::lastCharacterDeleted( SmartRange * )
{
}

#include "range.moc"

// kate: space-indent on; indent-width 2; replace-tabs on;
<commit_msg>first save everything, than commit :(<commit_after>/* This file is part of the KDE libraries
   Copyright (C) 2003-2005 Hamish Rodda <rodda@kde.org>
   Copyright (C) 2002 Christian Couder <christian@kdevelop.org>
   Copyright (C) 2001, 2003 Christoph Cullmann <cullmann@kde.org>
   Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
   Copyright (C) 1999 Jochen Wilhelmy <digisnap@cs.tu-berlin.de>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License version 2 as published by the Free Software Foundation.

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

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.
*/

#include "range.h"

#include "document.h"
#include "view.h"
#include "attribute.h"

#include <kaction.h>

using namespace KTextEditor;

Range::Range()
  : m_start(new Cursor())
  , m_end(new Cursor())
{
}

Range::Range(const Cursor& start, const Cursor& end)
  : m_start(new Cursor(start))
  , m_end(new Cursor(end))
{
}

Range::Range(const Cursor& start, int width)
  : m_start(new Cursor(start))
  , m_end(new Cursor(start.line(), start.column() + width))
{
}

Range::Range(const Cursor& start, int endLine, int endCol)
  : m_start(new Cursor(start))
  , m_end(new Cursor(endLine, endCol))
{
}

Range::Range(int startLine, int startCol, int endLine, int endCol)
  : m_start(new Cursor(startLine, startCol))
  , m_end(new Cursor(endLine, endCol))
{
}

Range::Range(Cursor* start, Cursor* end)
  : m_start(start)
  , m_end(end)
{
}

Range::Range(const Range& copy)
  : m_start(new Cursor(copy.start()))
  , m_end(new Cursor(copy.end()))
{
}

Range::~Range()
{
  delete m_start;
  delete m_end;
}

Range& Range::operator= (const Range& rhs)
{
  if (this == &rhs)
    return *this;

  setRange(rhs);

  return *this;
}

void Range::setStart(const Cursor& newStart)
{
  *m_start = newStart;
  if (start() > end())
    *m_end = newStart;
}

void Range::setEnd(const Cursor& newEnd)
{
  *m_end = newEnd;
  if (start() > end())
    *m_start = newEnd;
}

void Range::setRange(const Range& range)
{
  *m_start = range.start();
  *m_end = range.end();
}

void Range::setRange( const Cursor & start, const Cursor & end )
{
  if (start > end) {
    *m_start = end;
    *m_end = start;
  } else {
    *m_start = start;
    *m_end = end;
  }
}

bool Range::containsLine(int line) const
{
  return (line > start().line() || line == start().line() && !start().column()) && line < end().line();
}

bool Range::includesLine(int line) const
{
  return line >= start().line() && line <= end().line();
}

bool Range::spansColumn( int col ) const
{
  return start().column() <= col && end().column() > col;
}

bool Range::contains( const Cursor& cursor ) const
{
  return cursor >= start() && cursor < end();
}

bool Range::contains( const Range& range ) const
{
  return range.start() >= start() && range.end() <= end();
}

bool Range::overlaps( const Range& range ) const
{
  if (range.start() <= start())
    return range.end() > start();

  else if (range.end() >= end())
    return range.start() < end();

  else
    return contains(range);
}

bool Range::boundaryAt(const KTextEditor::Cursor& cursor) const
{
  return cursor == start() || cursor == end();
}

bool Range::boundaryOnLine(int line) const
{
  return start().line() == line || end().line() == line;
}

void Range::confineToRange(const Range& range)
{
  if (start() < range.start())
    if (end() < range.end())
      setRange(range);
    else
      setStart(range.start());
  else if (end() < range.end())
    setEnd(range.end());
}

void SmartRange::confineToRange(const Range& range)
{
  if (start() < range.start())
    if (end() < range.end())
      setRange(range);
    else
      setStart(range.start());
  else if (end() < range.end())
    setEnd(range.end());
  else
    // Don't need to check if children should be confined, they already are
    return;

  foreach (SmartRange* child, m_childRanges)
    child->confineToRange(*this);
}

SmartRange::SmartRange(SmartCursor* start, SmartCursor* end, SmartRange * parent, int insertBehaviour )
  : Range(start, end)
  , m_attribute(0L)
  , m_parentRange(parent)
  , m_insertBehaviour(insertBehaviour)
  , m_ownsAttribute(false)
{
  start->setBelongsToRange(this);
  end->setBelongsToRange(this);
}

SmartRange * SmartRange::childBefore( const SmartRange * range ) const
{
  int index = m_childRanges.indexOf(const_cast<SmartRange*>(range));
  if (index != -1 && --index > 0)
    return m_childRanges[index];
  return 0L;
}

SmartRange * SmartRange::childAfter( const SmartRange * range ) const
{
  int index = m_childRanges.indexOf(const_cast<SmartRange*>(range));
  if (index != -1 && ++index < m_childRanges.count())
    return m_childRanges[index];
  return 0L;
}

void SmartRange::setAttribute( Attribute * attribute, bool ownsAttribute )
{
  if (m_ownsAttribute)
      delete m_attribute;
  m_attribute = attribute;
  m_ownsAttribute = ownsAttribute;
}

SmartRange::~SmartRange( )
{
  if (m_ownsAttribute)
    delete m_attribute;

  /*if (!m_deleteCursors)
  {
    // Save from deletion in the parent
    m_start = 0L;
    m_end = 0L;
  }*/
}

SmartRange * KTextEditor::SmartRange::findMostSpecificRange( const Range & input ) const
{
  if (contains(input)) {
    for (QList<SmartRange*>::ConstIterator it = m_childRanges.constBegin(); it != m_childRanges.constEnd(); ++it)
      if ((*it)->contains(input))
        return (*it)->findMostSpecificRange(input);

    return const_cast<SmartRange*>(this);

  } else if (parentRange()) {
    return parentRange()->findMostSpecificRange(input);

  } else {
    return 0L;
  }
}

SmartRange * KTextEditor::SmartRange::firstRangeIncluding( const Cursor & pos ) const
{
  switch (relativePosition(pos)) {
    case 0:
      if (parentRange() && parentRange()->contains(pos))
        return parentRange()->firstRangeIncluding(pos);

      return const_cast<SmartRange*>(this);

    case -1:
      if (!parentRange())
        return 0L;

      if (!parentRange()->contains(pos))
        return parentRange()->firstRangeIncluding(pos);

      if (SmartRange* r = parentRange()->childAfter(this))
        return r->firstRangeIncluding(pos);

      return 0L;

    case 1:
      if (!parentRange())
        return 0L;

      if (!parentRange()->contains(pos))
        return parentRange()->firstRangeIncluding(pos);

      if (const SmartRange* r = parentRange()->childBefore(this))
        return r->firstRangeIncluding(pos);

      return 0L;

    default:
      Q_ASSERT(false);
      return 0L;
  }
}

SmartRange * KTextEditor::SmartRange::deepestRangeContaining( const Cursor & pos ) const
{
  switch (relativePosition(pos)) {
    case 0:
      for (QList<SmartRange*>::ConstIterator it = m_childRanges.constBegin(); it != m_childRanges.constEnd(); ++it)
        if ((*it)->contains(pos) == 0)
          return ((*it)->deepestRangeContaining(pos));

      return const_cast<SmartRange*>(this);

    case -1:
      if (!parentRange())
        return 0L;

      if (!parentRange()->contains(pos))
        return parentRange()->deepestRangeContaining(pos);

      if (const SmartRange* r = parentRange()->childAfter(this))
        return r->deepestRangeContaining(pos);

      return 0L;

    case 1:
      if (!parentRange())
        return 0L;

      if (!parentRange()->contains(pos))
        return parentRange()->deepestRangeContaining(pos);

      if (const SmartRange* r = parentRange()->childBefore(this))
        return r->firstRangeIncluding(pos);

      return 0L;

    default:
      Q_ASSERT(false);
      return 0L;
  }
}

Document* SmartRange::document( ) const
{
  return smartStart().document();
}

void SmartRange::attachAction( KAction * action )
{
  m_associatedActions.append(action);

  bool enable = false;
  if (View* v = document()->activeView())
    if (contains(v->cursorPosition()))
      enable = true;

  action->setEnabled(enable);

  if (m_associatedActions.count() == 1)
    checkFeedback();
}

void SmartRange::detachAction( KAction * action )
{
  m_associatedActions.remove(action);
  if (!m_associatedActions.count())
    checkFeedback();
}

int SmartRange::insertBehaviour( ) const
{
  return (smartStart().moveOnInsert() ? DoNotExpand : ExpandLeft) | (smartEnd().moveOnInsert() ? ExpandRight : DoNotExpand);
}

void SmartRange::setInsertBehaviour(int behaviour)
{
  static_cast<SmartCursor*>(m_start)->setMoveOnInsert(behaviour & ExpandLeft);
  static_cast<SmartCursor*>(m_end)->setMoveOnInsert(!(behaviour & ExpandRight));
}

void SmartRange::clearAllChildRanges()
{
  while (m_childRanges.count()) {
    KTextEditor::Range* r = m_childRanges.first();
    m_childRanges.remove(m_childRanges.begin());

    delete r;
  }
}

void SmartRange::deleteAllChildRanges()
{
  while (m_childRanges.count()) {
    KTextEditor::Range* r = m_childRanges.first();
    m_childRanges.remove(m_childRanges.begin());

    // FIXME editDeleteText here? or a call to delete the text on the range object
    delete r;
  }
}

const Range& Range::invalid()
{
  static Range r;
  if (r.start().line() != -1)
    r.setRange(Cursor(-1,-1),Cursor(-1,-1));
  return r;
}

KTextEditor::SmartRangeWatcher::~ SmartRangeWatcher( )
{
}

void KTextEditor::SmartRangeWatcher::positionChanged( SmartRange * )
{
}

void KTextEditor::SmartRangeWatcher::contentsChanged( SmartRange * )
{
}

void KTextEditor::SmartRangeWatcher::boundaryDeleted( SmartRange * , bool )
{
}

void KTextEditor::SmartRangeWatcher::eliminated( SmartRange * )
{
}

void KTextEditor::SmartRangeWatcher::firstCharacterDeleted( SmartRange * )
{
}

void KTextEditor::SmartRangeWatcher::lastCharacterDeleted( SmartRange * )
{
}

#include "range.moc"

// kate: space-indent on; indent-width 2; replace-tabs on;
<|endoftext|>


<commit_before><commit_msg>fix compiler error<commit_after><|endoftext|>


<commit_before><commit_msg>Update utilitydialog.cpp<commit_after><|endoftext|>


<commit_before><commit_msg>Fixed assert on Linux<commit_after><|endoftext|>


<commit_before>/*
 * Copyright (c) 2008 Princeton University
 * 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 copyright holders 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.
 *
 * Authors: Niket Agarwal
 */

#ifndef __MEM_RUBY_NETWORK_GARNET_FIXED_PIPELINE_NETWORK_LINK_D_HH__
#define __MEM_RUBY_NETWORK_GARNET_FIXED_PIPELINE_NETWORK_LINK_D_HH__

#include <iostream>
#include <vector>

#include "mem/ruby/common/Consumer.hh"
#include "mem/ruby/network/garnet/fixed-pipeline/flitBuffer_d.hh"
#include "mem/ruby/network/garnet/NetworkHeader.hh"
#include "params/NetworkLink_d.hh"
#include "sim/clocked_object.hh"

class GarnetNetwork_d;

class NetworkLink_d : public ClockedObject, public Consumer
{
  public:
    typedef NetworkLink_dParams Params;
    NetworkLink_d(const Params *p);
    ~NetworkLink_d();

    void setLinkConsumer(Consumer *consumer);
    void setSourceQueue(flitBuffer_d *srcQueue);
    void print(std::ostream& out) const{}
    int get_id(){return m_id;}
    void wakeup();

    unsigned int getLinkUtilization() const { return m_link_utilized; }
    const std::vector<unsigned int> & getVcLoad() const { return m_vc_load; }

    inline bool isReady(Cycles curTime)
    { return linkBuffer->isReady(curTime); }

    inline flit_d* peekLink()       { return linkBuffer->peekTopFlit(); }
    inline flit_d* consumeLink()    { return linkBuffer->getTopFlit(); }

    uint32_t functionalWrite(Packet *);

  private:
    int m_id;
    Cycles m_latency;
    int channel_width;

    flitBuffer_d *linkBuffer;
    Consumer *link_consumer;
    flitBuffer_d *link_srcQueue;
    int m_flit_width;

    // Statistical variables
    unsigned int m_link_utilized;
    std::vector<unsigned int> m_vc_load;
};

#endif // __MEM_RUBY_NETWORK_GARNET_FIXED_PIPELINE_NETWORK_LINK_D_HH__
<commit_msg>mem: Delete unused variable in Garnet NetworkLink<commit_after>/*
 * Copyright (c) 2008 Princeton University
 * 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 copyright holders 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.
 *
 * Authors: Niket Agarwal
 */

#ifndef __MEM_RUBY_NETWORK_GARNET_FIXED_PIPELINE_NETWORK_LINK_D_HH__
#define __MEM_RUBY_NETWORK_GARNET_FIXED_PIPELINE_NETWORK_LINK_D_HH__

#include <iostream>
#include <vector>

#include "mem/ruby/common/Consumer.hh"
#include "mem/ruby/network/garnet/fixed-pipeline/flitBuffer_d.hh"
#include "mem/ruby/network/garnet/NetworkHeader.hh"
#include "params/NetworkLink_d.hh"
#include "sim/clocked_object.hh"

class GarnetNetwork_d;

class NetworkLink_d : public ClockedObject, public Consumer
{
  public:
    typedef NetworkLink_dParams Params;
    NetworkLink_d(const Params *p);
    ~NetworkLink_d();

    void setLinkConsumer(Consumer *consumer);
    void setSourceQueue(flitBuffer_d *srcQueue);
    void print(std::ostream& out) const{}
    int get_id(){return m_id;}
    void wakeup();

    unsigned int getLinkUtilization() const { return m_link_utilized; }
    const std::vector<unsigned int> & getVcLoad() const { return m_vc_load; }

    inline bool isReady(Cycles curTime)
    { return linkBuffer->isReady(curTime); }

    inline flit_d* peekLink()       { return linkBuffer->peekTopFlit(); }
    inline flit_d* consumeLink()    { return linkBuffer->getTopFlit(); }

    uint32_t functionalWrite(Packet *);

  private:
    int m_id;
    Cycles m_latency;
    int channel_width;

    flitBuffer_d *linkBuffer;
    Consumer *link_consumer;
    flitBuffer_d *link_srcQueue;

    // Statistical variables
    unsigned int m_link_utilized;
    std::vector<unsigned int> m_vc_load;
};

#endif // __MEM_RUBY_NETWORK_GARNET_FIXED_PIPELINE_NETWORK_LINK_D_HH__
<|endoftext|>