<commit_before>#include "stdafx.h"

#include "ext/phonebook/phonebook.h"
#include "NativeAddressBook.h"

#define INITGUID
#include <pimstore.h>
#include <comutil.h>

IMPLEMENT_LOGCLASS(CABRecord,"ABRecord");
IMPLEMENT_LOGCLASS(CABOutlookRecord,"ABOutlookRecord");
IMPLEMENT_LOGCLASS(CNativeAddressBook,"NativeAddressBook");

std::string bstr2str(BSTR s) {
	_bstr_t bstr(s);
	return (LPCSTR)bstr;
}

std::string& CABRecord::getValue(std::string field) {
	return m_props[field];
}

int CABRecord::setValue(std::string field,std::string value) {
	m_props[field] = value;
	return 1;
}

void CABRecord::enumValues(ab_callback_t proc,void* param) {
	std::map<std::string,std::string>::iterator it;
	for ( it = m_props.begin(); it != m_props.end(); it++ ) {
		(*proc)((*it).first.c_str(),(*it).second.c_str(),param);
	}
}

void CABRecord::dump() {
	LOG(INFO) + "Record dump ================================================";
	std::map<std::string,std::string>::iterator it;
	for ( it = m_props.begin(); it != m_props.end(); it++ ) {
		LOG(INFO) + "[" + (*it).first.c_str() + "] -> [" + (*it).second.c_str() + "]";
	}
	LOG(INFO) + "End of record dump =========================================";
}

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

CABOutlookRecord::CABOutlookRecord(IContact* pContact) :
m_pContact(pContact) {
	m_type = eOutlookContact;
	m_modifyed = false;
}

CABOutlookRecord::~CABOutlookRecord() {
	if (m_pContact) {
		m_pContact->Release();
	}
}

int CABOutlookRecord::load() {
	if (m_pContact) {
		long oid;
		if(SUCCEEDED(m_pContact->get_Oid(&oid) ) ) {
			char buf[128];
			sprintf(buf,"{outlook %ld}",oid);
			setValue(RUBY_PB_ID,buf);
		}

		BSTR pwsz = NULL;
		if(SUCCEEDED(m_pContact->get_MobileTelephoneNumber(&pwsz) ) ) {
			if(pwsz[0]!=0) {
				std::string const &number = bstr2str(pwsz);
				setValue(RUBY_PB_MOBILE_NUMBER,number);
			}
			::SysFreeString( pwsz);
		}

		if(SUCCEEDED(m_pContact->get_HomeTelephoneNumber(&pwsz) ) ) {
			if(pwsz[0]!=0) {
				std::string const &number = bstr2str(pwsz);
				setValue(RUBY_PB_HOME_NUMBER,number);
			}
			::SysFreeString( pwsz);
		}

		if(SUCCEEDED(m_pContact->get_BusinessTelephoneNumber(&pwsz) ) ) {
			if(pwsz[0]!=0) {
				std::string const &number = bstr2str(pwsz);
				setValue(RUBY_PB_BUSINESS_NUMBER,number);
			}
			::SysFreeString( pwsz);
		}

		if(SUCCEEDED(m_pContact->get_FirstName(&pwsz) ) ) {
			if(pwsz[0]!=0) {
				std::string const &name = bstr2str(pwsz);
				setValue(RUBY_PB_FIRST_NAME,name);
			}
			::SysFreeString(pwsz);
		}

		if(SUCCEEDED(m_pContact->get_LastName(&pwsz) ) ) {
			if(pwsz[0]!=0) {
				std::string const &name = bstr2str(pwsz);
				setValue(RUBY_PB_LAST_NAME,name);
			}
			::SysFreeString(pwsz);
		}

		if(SUCCEEDED(m_pContact->get_CompanyName(&pwsz) ) ) {
			if(pwsz[0]!=0) {
				std::string const &name = bstr2str(pwsz);
				setValue(RUBY_PB_COMPANY_NAME,name);
			}
			::SysFreeString(pwsz);
		}

		if(SUCCEEDED(m_pContact->get_Email1Address(&pwsz) ) ) {
			if(pwsz[0]!=0) {
				std::string const &address = bstr2str(pwsz);
				setValue(RUBY_PB_EMAIL_ADDRESS,address);
			}
			::SysFreeString(pwsz);
		}

	}
	return 1;
}

void CABOutlookRecord::saveValues() {
	const char* value = getValue(RUBY_PB_MOBILE_NUMBER).c_str();
	if (value!=NULL) {
		m_pContact->put_MobileTelephoneNumber(_bstr_t(value));
	}
	value = getValue(RUBY_PB_HOME_NUMBER).c_str();
	if (value!=NULL) {
		m_pContact->put_HomeTelephoneNumber(_bstr_t(value));
	}
	value = getValue(RUBY_PB_BUSINESS_NUMBER).c_str();
	if (value!=NULL) {
		m_pContact->put_BusinessTelephoneNumber(_bstr_t(value));
	}

	value = getValue(RUBY_PB_FIRST_NAME).c_str();
	if (value!=NULL) {
		m_pContact->put_FirstName(_bstr_t(value));
	}
	value = getValue(RUBY_PB_LAST_NAME).c_str();
	if (value!=NULL) {
		m_pContact->put_LastName(_bstr_t(value));
	}
	value = getValue(RUBY_PB_COMPANY_NAME).c_str();
	if (value!=NULL) {
		m_pContact->put_CompanyName(_bstr_t(value));
	}
	value = getValue(RUBY_PB_EMAIL_ADDRESS).c_str();
	if (value!=NULL) {
		m_pContact->put_Email1Address(_bstr_t(value));
	}
}

int CABOutlookRecord::save() {
	if (m_pContact) {
		saveValues();
		m_pContact->Save();
	}
	return 1;
}

int CABOutlookRecord::remove() {
	if (m_pContact) {
		m_pContact->Delete();
	}
	return 1;
}

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

CNativeAddressBook::CNativeAddressBook() :
m_openedOutlookAB(false), m_outlookApp(NULL), m_outlookItems(NULL) {
}

CNativeAddressBook::~CNativeAddressBook() {
	if (m_openedOutlookAB) {
		closeOutlookAB();
	}
}

int CNativeAddressBook::openAB() {
	return initOutlookAB();
}

int CNativeAddressBook::getAllRecords(std::vector<CABRecord*>& records) {
	return getAllOutlookRecords(records);
}

CABRecord* CNativeAddressBook::getRecord(char* id) {
	char recordType[20];
	long recordId;
	if ( sscanf(id, "{%s %ld}", recordType, &recordId) == 2 ) {
		LOG(INFO) + "get Record " + recordId + " of " + recordType +" type";
		if (strcmp(recordType,"outlook")==0) {
			return getOutlookRecord(recordId);
		}
	}
	return NULL;
}

int CNativeAddressBook::addRecord(CABRecord* record) {
	return addOutlookRecord((CABOutlookRecord*)record);
}

int CNativeAddressBook::deleteRecord(CABRecord* record) {
	return 1;
}

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

int CNativeAddressBook::initOutlookAB() {
	m_openedOutlookAB = false;

    HRESULT hr = CoInitializeEx( NULL, 0);
	// subsequent valid calls return S_FALSE
    /*if (hr != S_OK) {
        // CoInitializeEx failed.
        LOG(ERROR) + "CoInitializeEx failed.";
        return false;  // Replace with specific error handling.;
    }*/

    IUnknown* pUnknown = NULL;
    hr = CoCreateInstance(__uuidof(Application),//CLSID_Application,
        NULL, CLSCTX_INPROC_SERVER,
        IID_IUnknown,
        (void **)&pUnknown);
    if (hr != S_OK) {
        // CoCreateInstance failed.
        LOG(ERROR) + "CoCreateInstance failed.";
        CoUninitialize();
        return false;  // Replace with specific error handling.;
    }

    hr = pUnknown->QueryInterface(__uuidof(IPOutlookApp)/*IID_IPOutlookApp*/, (void**)&m_outlookApp);
    if (hr != S_OK) {
        // QueryInterface failed.
        LOG(ERROR) + "QueryInterface failed.";
        CoUninitialize();
        return false;  // Replace with specific error handling.;
    }

    hr = m_outlookApp->Logon(NULL);
    if (hr != S_OK) {
        // Logon failed.
        LOG(ERROR) + "Logon failed.";
        m_outlookApp->Release();
        CoUninitialize();
        return false;  // Replace with specific error handling.;
    }

    m_openedOutlookAB = true;
    return m_openedOutlookAB;
}

int CNativeAddressBook::closeOutlookAB() {
	if(m_outlookItems) {
		m_outlookItems->Release();
	}
	if(m_outlookApp) {
		m_outlookApp->Release();
		CoUninitialize();
	}
	return 1;
}

bool CNativeAddressBook::getOutlookItems() {
	if( (m_outlookApp!=NULL)&&(m_outlookItems==NULL)) {
		//
		IFolder* polFolder;
		HRESULT res = m_outlookApp->GetDefaultFolder(olFolderContacts, &polFolder);
		if (res != S_OK) {
			// QueryInterface failed.
			LOG(ERROR) + "GetDefaultFolder failed.";
			return false;
		}

		res = polFolder->get_Items(&m_outlookItems);
		if (res != S_OK) {
			// QueryInterface failed.
			polFolder->Release();
			LOG(ERROR) + "get_Items failed.";
			return false;
		}

		polFolder->Release();
	}
	return true;
}

int CNativeAddressBook::getAllOutlookRecords(std::vector<CABRecord*>& records) {
	if(m_outlookApp && getOutlookItems()) {
		int size;
		m_outlookItems->get_Count(&size);

		IContact * pContact;
		CABOutlookRecord *pRecord;
		for(int index = 1; index <= size; ++index) {
			m_outlookItems->Item(index, (IDispatch**)&pContact);
			pRecord = new CABOutlookRecord(pContact);
			if(pRecord) {
				pRecord->load();
				records.push_back(pRecord);
			} else {
				pContact->Release();
			}
		}
	}
	return 1;
}

CABRecord* CNativeAddressBook::getOutlookRecord(long oid) {
	if(m_outlookApp && getOutlookItems()) {
		DWORD index;
		if(S_OK==GetItemIndexFromOid(m_outlookItems,oid,&index)) {
			IContact * pContact;
			CABOutlookRecord *pRecord;
			if (SUCCEEDED(m_outlookItems->Item(1+index, (IDispatch**)&pContact))) {
				pRecord = new CABOutlookRecord(pContact);
				if(pRecord) {
					pRecord->load();
					return pRecord;
				} else {
					pContact->Release();
				}
			}
		}
	}
	return NULL;
}

int CNativeAddressBook::addOutlookRecord(CABOutlookRecord* record) {
	if(m_outlookApp && getOutlookItems()) {
		if(SUCCEEDED(m_outlookItems->Add((IDispatch**)&record->m_pContact))) {
			record->save();
		}
	}
	return 1;
}<commit_msg>Add comment explaining previous fix<commit_after>#include "stdafx.h"

#include "ext/phonebook/phonebook.h"
#include "NativeAddressBook.h"

#define INITGUID
#include <pimstore.h>
#include <comutil.h>

IMPLEMENT_LOGCLASS(CABRecord,"ABRecord");
IMPLEMENT_LOGCLASS(CABOutlookRecord,"ABOutlookRecord");
IMPLEMENT_LOGCLASS(CNativeAddressBook,"NativeAddressBook");

// Note that return type is std::string, not LPCSTR!!!
// It is required to get live object even after function exit
// In case if it is LPCSTR we actually get pointer to the
// dead object internal member
std::string bstr2str(BSTR s) {
	_bstr_t bstr(s);
	return (LPCSTR)bstr;
}

std::string& CABRecord::getValue(std::string field) {
	return m_props[field];
}

int CABRecord::setValue(std::string field,std::string value) {
	m_props[field] = value;
	return 1;
}

void CABRecord::enumValues(ab_callback_t proc,void* param) {
	std::map<std::string,std::string>::iterator it;
	for ( it = m_props.begin(); it != m_props.end(); it++ ) {
		(*proc)((*it).first.c_str(),(*it).second.c_str(),param);
	}
}

void CABRecord::dump() {
	LOG(INFO) + "Record dump ================================================";
	std::map<std::string,std::string>::iterator it;
	for ( it = m_props.begin(); it != m_props.end(); it++ ) {
		LOG(INFO) + "[" + (*it).first.c_str() + "] -> [" + (*it).second.c_str() + "]";
	}
	LOG(INFO) + "End of record dump =========================================";
}

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

CABOutlookRecord::CABOutlookRecord(IContact* pContact) :
m_pContact(pContact) {
	m_type = eOutlookContact;
	m_modifyed = false;
}

CABOutlookRecord::~CABOutlookRecord() {
	if (m_pContact) {
		m_pContact->Release();
	}
}

int CABOutlookRecord::load() {
	if (m_pContact) {
		long oid;
		if(SUCCEEDED(m_pContact->get_Oid(&oid) ) ) {
			char buf[128];
			sprintf(buf,"{outlook %ld}",oid);
			setValue(RUBY_PB_ID,buf);
		}

		BSTR pwsz = NULL;
		if(SUCCEEDED(m_pContact->get_MobileTelephoneNumber(&pwsz) ) ) {
			if(pwsz[0]!=0) {
				std::string const &number = bstr2str(pwsz);
				setValue(RUBY_PB_MOBILE_NUMBER,number);
			}
			::SysFreeString( pwsz);
		}

		if(SUCCEEDED(m_pContact->get_HomeTelephoneNumber(&pwsz) ) ) {
			if(pwsz[0]!=0) {
				std::string const &number = bstr2str(pwsz);
				setValue(RUBY_PB_HOME_NUMBER,number);
			}
			::SysFreeString( pwsz);
		}

		if(SUCCEEDED(m_pContact->get_BusinessTelephoneNumber(&pwsz) ) ) {
			if(pwsz[0]!=0) {
				std::string const &number = bstr2str(pwsz);
				setValue(RUBY_PB_BUSINESS_NUMBER,number);
			}
			::SysFreeString( pwsz);
		}

		if(SUCCEEDED(m_pContact->get_FirstName(&pwsz) ) ) {
			if(pwsz[0]!=0) {
				std::string const &name = bstr2str(pwsz);
				setValue(RUBY_PB_FIRST_NAME,name);
			}
			::SysFreeString(pwsz);
		}

		if(SUCCEEDED(m_pContact->get_LastName(&pwsz) ) ) {
			if(pwsz[0]!=0) {
				std::string const &name = bstr2str(pwsz);
				setValue(RUBY_PB_LAST_NAME,name);
			}
			::SysFreeString(pwsz);
		}

		if(SUCCEEDED(m_pContact->get_CompanyName(&pwsz) ) ) {
			if(pwsz[0]!=0) {
				std::string const &name = bstr2str(pwsz);
				setValue(RUBY_PB_COMPANY_NAME,name);
			}
			::SysFreeString(pwsz);
		}

		if(SUCCEEDED(m_pContact->get_Email1Address(&pwsz) ) ) {
			if(pwsz[0]!=0) {
				std::string const &address = bstr2str(pwsz);
				setValue(RUBY_PB_EMAIL_ADDRESS,address);
			}
			::SysFreeString(pwsz);
		}

	}
	return 1;
}

void CABOutlookRecord::saveValues() {
	const char* value = getValue(RUBY_PB_MOBILE_NUMBER).c_str();
	if (value!=NULL) {
		m_pContact->put_MobileTelephoneNumber(_bstr_t(value));
	}
	value = getValue(RUBY_PB_HOME_NUMBER).c_str();
	if (value!=NULL) {
		m_pContact->put_HomeTelephoneNumber(_bstr_t(value));
	}
	value = getValue(RUBY_PB_BUSINESS_NUMBER).c_str();
	if (value!=NULL) {
		m_pContact->put_BusinessTelephoneNumber(_bstr_t(value));
	}

	value = getValue(RUBY_PB_FIRST_NAME).c_str();
	if (value!=NULL) {
		m_pContact->put_FirstName(_bstr_t(value));
	}
	value = getValue(RUBY_PB_LAST_NAME).c_str();
	if (value!=NULL) {
		m_pContact->put_LastName(_bstr_t(value));
	}
	value = getValue(RUBY_PB_COMPANY_NAME).c_str();
	if (value!=NULL) {
		m_pContact->put_CompanyName(_bstr_t(value));
	}
	value = getValue(RUBY_PB_EMAIL_ADDRESS).c_str();
	if (value!=NULL) {
		m_pContact->put_Email1Address(_bstr_t(value));
	}
}

int CABOutlookRecord::save() {
	if (m_pContact) {
		saveValues();
		m_pContact->Save();
	}
	return 1;
}

int CABOutlookRecord::remove() {
	if (m_pContact) {
		m_pContact->Delete();
	}
	return 1;
}

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

CNativeAddressBook::CNativeAddressBook() :
m_openedOutlookAB(false), m_outlookApp(NULL), m_outlookItems(NULL) {
}

CNativeAddressBook::~CNativeAddressBook() {
	if (m_openedOutlookAB) {
		closeOutlookAB();
	}
}

int CNativeAddressBook::openAB() {
	return initOutlookAB();
}

int CNativeAddressBook::getAllRecords(std::vector<CABRecord*>& records) {
	return getAllOutlookRecords(records);
}

CABRecord* CNativeAddressBook::getRecord(char* id) {
	char recordType[20];
	long recordId;
	if ( sscanf(id, "{%s %ld}", recordType, &recordId) == 2 ) {
		LOG(INFO) + "get Record " + recordId + " of " + recordType +" type";
		if (strcmp(recordType,"outlook")==0) {
			return getOutlookRecord(recordId);
		}
	}
	return NULL;
}

int CNativeAddressBook::addRecord(CABRecord* record) {
	return addOutlookRecord((CABOutlookRecord*)record);
}

int CNativeAddressBook::deleteRecord(CABRecord* record) {
	return 1;
}

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

int CNativeAddressBook::initOutlookAB() {
	m_openedOutlookAB = false;

    HRESULT hr = CoInitializeEx( NULL, 0);
	// subsequent valid calls return S_FALSE
    /*if (hr != S_OK) {
        // CoInitializeEx failed.
        LOG(ERROR) + "CoInitializeEx failed.";
        return false;  // Replace with specific error handling.;
    }*/

    IUnknown* pUnknown = NULL;
    hr = CoCreateInstance(__uuidof(Application),//CLSID_Application,
        NULL, CLSCTX_INPROC_SERVER,
        IID_IUnknown,
        (void **)&pUnknown);
    if (hr != S_OK) {
        // CoCreateInstance failed.
        LOG(ERROR) + "CoCreateInstance failed.";
        CoUninitialize();
        return false;  // Replace with specific error handling.;
    }

    hr = pUnknown->QueryInterface(__uuidof(IPOutlookApp)/*IID_IPOutlookApp*/, (void**)&m_outlookApp);
    if (hr != S_OK) {
        // QueryInterface failed.
        LOG(ERROR) + "QueryInterface failed.";
        CoUninitialize();
        return false;  // Replace with specific error handling.;
    }

    hr = m_outlookApp->Logon(NULL);
    if (hr != S_OK) {
        // Logon failed.
        LOG(ERROR) + "Logon failed.";
        m_outlookApp->Release();
        CoUninitialize();
        return false;  // Replace with specific error handling.;
    }

    m_openedOutlookAB = true;
    return m_openedOutlookAB;
}

int CNativeAddressBook::closeOutlookAB() {
	if(m_outlookItems) {
		m_outlookItems->Release();
	}
	if(m_outlookApp) {
		m_outlookApp->Release();
		CoUninitialize();
	}
	return 1;
}

bool CNativeAddressBook::getOutlookItems() {
	if( (m_outlookApp!=NULL)&&(m_outlookItems==NULL)) {
		//
		IFolder* polFolder;
		HRESULT res = m_outlookApp->GetDefaultFolder(olFolderContacts, &polFolder);
		if (res != S_OK) {
			// QueryInterface failed.
			LOG(ERROR) + "GetDefaultFolder failed.";
			return false;
		}

		res = polFolder->get_Items(&m_outlookItems);
		if (res != S_OK) {
			// QueryInterface failed.
			polFolder->Release();
			LOG(ERROR) + "get_Items failed.";
			return false;
		}

		polFolder->Release();
	}
	return true;
}

int CNativeAddressBook::getAllOutlookRecords(std::vector<CABRecord*>& records) {
	if(m_outlookApp && getOutlookItems()) {
		int size;
		m_outlookItems->get_Count(&size);

		IContact * pContact;
		CABOutlookRecord *pRecord;
		for(int index = 1; index <= size; ++index) {
			m_outlookItems->Item(index, (IDispatch**)&pContact);
			pRecord = new CABOutlookRecord(pContact);
			if(pRecord) {
				pRecord->load();
				records.push_back(pRecord);
			} else {
				pContact->Release();
			}
		}
	}
	return 1;
}

CABRecord* CNativeAddressBook::getOutlookRecord(long oid) {
	if(m_outlookApp && getOutlookItems()) {
		DWORD index;
		if(S_OK==GetItemIndexFromOid(m_outlookItems,oid,&index)) {
			IContact * pContact;
			CABOutlookRecord *pRecord;
			if (SUCCEEDED(m_outlookItems->Item(1+index, (IDispatch**)&pContact))) {
				pRecord = new CABOutlookRecord(pContact);
				if(pRecord) {
					pRecord->load();
					return pRecord;
				} else {
					pContact->Release();
				}
			}
		}
	}
	return NULL;
}

int CNativeAddressBook::addOutlookRecord(CABOutlookRecord* record) {
	if(m_outlookApp && getOutlookItems()) {
		if(SUCCEEDED(m_outlookItems->Add((IDispatch**)&record->m_pContact))) {
			record->save();
		}
	}
	return 1;
}<|endoftext|>


<commit_before>#include "catch.hpp"
#include "matrix.h"

TEST_CASE( "Test matrix comparison", "[matrix][comparison]" ) {
  SECTION("Compare empty matrixes"){
    matrix<int> m1 = {};
    matrix<int> m2 = {};
    REQUIRE( m1 == m2 );
  }
  SECTION("Compare 1x1 matrixes"){
    matrix<int> m1 = {{0}};
    matrix<int> m2(1,1);
    REQUIRE( m1 == m2 );
  }
  SECTION("Compare 2x2 matrixes"){
    matrix<int> m1 = {{1,2},{3,4}};
    matrix<int> m2 = {{1,2},{3,4}};
    REQUIRE( m1 == m2 );
  }
  SECTION("Compare different 2x2 matrixes"){
    matrix<int> m1 = {{1,2},{3,4}};
    matrix<int> m2 = {{1,1},{2,2}};
    REQUIRE( m1 != m2 );
  }
  SECTION("Compare 2x2 matrix with 2x3 matrix"){
    matrix<int> m1 = {{1,2},{3,4}};
    matrix<int> m2 = {{1,2,3},{4,5,6}};
    REQUIRE( m1 != m2 );
  }
  SECTION("Compare 3x2 matrix with 2x3 matrix"){
    matrix<int> m1 = {{1,2},{3,4},{5,6}};
    matrix<int> m2 = {{1,2,3},{4,5,6}};
    REQUIRE( m1 != m2 );
  }
}
<commit_msg>Fix spelling.<commit_after>#include "catch.hpp"
#include "matrix.h"

TEST_CASE( "Test matrix comparison", "[matrix][comparison]" ) {
  SECTION("Compare empty matrices"){
    matrix<int> m1 = {};
    matrix<int> m2 = {};
    REQUIRE( m1 == m2 );
  }
  SECTION("Compare 1x1 matrices"){
    matrix<int> m1 = {{0}};
    matrix<int> m2(1,1);
    REQUIRE( m1 == m2 );
  }
  SECTION("Compare 2x2 matrices"){
    matrix<int> m1 = {{1,2},{3,4}};
    matrix<int> m2 = {{1,2},{3,4}};
    REQUIRE( m1 == m2 );
  }
  SECTION("Compare different 2x2 matrices"){
    matrix<int> m1 = {{1,2},{3,4}};
    matrix<int> m2 = {{1,1},{2,2}};
    REQUIRE( m1 != m2 );
  }
  SECTION("Compare 2x2 matrix with 2x3 matrix"){
    matrix<int> m1 = {{1,2},{3,4}};
    matrix<int> m2 = {{1,2,3},{4,5,6}};
    REQUIRE( m1 != m2 );
  }
  SECTION("Compare 3x2 matrix with 2x3 matrix"){
    matrix<int> m1 = {{1,2},{3,4},{5,6}};
    matrix<int> m2 = {{1,2,3},{4,5,6}};
    REQUIRE( m1 != m2 );
  }
}
<|endoftext|>


<commit_before>// RUN: %clangxx_asan %s -o %t && %run %t
// http://code.google.com/p/address-sanitizer/issues/detail?id=147 (not fixed).
// BROKEN: %clangxx_asan %s -o %t -static-libstdc++ && %run %t
//
// Android builds with static libstdc++ by default.
// XFAIL: android

#include <stdio.h>
static volatile int zero = 0;
inline void pretend_to_do_something(void *x) {
  __asm__ __volatile__("" : : "r" (x) : "memory");
}

__attribute__((noinline, no_sanitize_address))
void ReallyThrow() {
  fprintf(stderr, "ReallyThrow\n");
  if (zero == 0)
    throw 42;
}

__attribute__((noinline))
void Throw() {
  int a, b, c, d, e, f, g, h;
  pretend_to_do_something(&a);
  pretend_to_do_something(&b);
  pretend_to_do_something(&c);
  pretend_to_do_something(&d);
  pretend_to_do_something(&e);
  pretend_to_do_something(&f);
  pretend_to_do_something(&g);
  pretend_to_do_something(&h);
  fprintf(stderr, "Throw stack = %p\n", &a);
  ReallyThrow();
}

__attribute__((noinline))
void CheckStack() {
  int ar[100];
  pretend_to_do_something(ar);
  fprintf(stderr, "CheckStack stack = %p, %p\n", ar, ar + 100);
  for (int i = 0; i < 100; i++)
    ar[i] = i;
}

int main(int argc, char** argv) {
  try {
    Throw();
  } catch(int a) {
    fprintf(stderr, "a = %d\n", a);
  }
  CheckStack();
}
<commit_msg>[asan] This test now passes<commit_after>// RUN: %clangxx_asan %s -o %t && %run %t
// http://code.google.com/p/address-sanitizer/issues/detail?id=147 (not fixed).
// BROKEN: %clangxx_asan %s -o %t -static-libstdc++ && %run %t

#include <stdio.h>
static volatile int zero = 0;
inline void pretend_to_do_something(void *x) {
  __asm__ __volatile__("" : : "r" (x) : "memory");
}

__attribute__((noinline, no_sanitize_address))
void ReallyThrow() {
  fprintf(stderr, "ReallyThrow\n");
  if (zero == 0)
    throw 42;
}

__attribute__((noinline))
void Throw() {
  int a, b, c, d, e, f, g, h;
  pretend_to_do_something(&a);
  pretend_to_do_something(&b);
  pretend_to_do_something(&c);
  pretend_to_do_something(&d);
  pretend_to_do_something(&e);
  pretend_to_do_something(&f);
  pretend_to_do_something(&g);
  pretend_to_do_something(&h);
  fprintf(stderr, "Throw stack = %p\n", &a);
  ReallyThrow();
}

__attribute__((noinline))
void CheckStack() {
  int ar[100];
  pretend_to_do_something(ar);
  fprintf(stderr, "CheckStack stack = %p, %p\n", ar, ar + 100);
  for (int i = 0; i < 100; i++)
    ar[i] = i;
}

int main(int argc, char** argv) {
  try {
    Throw();
  } catch(int a) {
    fprintf(stderr, "a = %d\n", a);
  }
  CheckStack();
}
<|endoftext|>


<commit_before>/** bidding_agent_ex.cc                                 -*- C++ -*-
    Rémi Attab, 22 Feb 2013
    Copyright (c) 2013 Datacratic.  All rights reserved.

    Example of a simple fixed-price bidding agent.

*/

#include "rtbkit/common/bids.h"
#include "rtbkit/core/banker/slave_banker.h"
#include "rtbkit/core/agent_configuration/agent_config.h"
#include "rtbkit/plugins/bidding_agent/bidding_agent.h"
#include "soa/service/service_utils.h"

#include <boost/program_options/cmdline.hpp>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/positional_options.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/variables_map.hpp>

#include <iostream>
#include <thread>
#include <chrono>
#include <string>     // std::string, std::to_string

using namespace std;
using namespace ML;

namespace RTBKIT {

/******************************************************************************/
/* FIXED PRICE BIDDING AGENT                                                  */
/******************************************************************************/

/** Simple bidding agent whose sole purpose in life is to bid 0.1$ CPM on every
    bid requests it sees. It also has a very simple pacer which ensures that we
    always have at most 1$ to spend every 10 seconds.

 */
struct FixedPriceBiddingAgent :
        public BiddingAgent
{
    FixedPriceBiddingAgent(
            std::shared_ptr<Datacratic::ServiceProxies> services,
            const string& serviceName) :
        BiddingAgent(services, serviceName),
        accountSetup(false)
    {}

    void init(const std::shared_ptr<ApplicationLayer> appLayer)
    {
        // We only want to specify a subset of the callbacks so turn the
        // annoying safety belt off.
        strictMode(false);

        onBidRequest = bind(
                &FixedPriceBiddingAgent::bid, this, _1, _2, _3, _4, _5, _6);

        // This component is used to speak with the master banker and pace the
        // rate at which we spend our budget.
        budgetController.setApplicationLayer(appLayer);
        budgetController.start();

        // Update our pacer every 10 seconds. Note that since this interacts
        // with the budgetController which is only synced up with the router
        // every few seconds, the wait period shouldn't be set too low.
        addPeriodic("FixedPriceBiddingAgent::pace", 10.0,
                [&] (uint64_t) { this->pace(); });

        BiddingAgent::init();

    }

    void start()
    {
        BiddingAgent::start();

        // Build our configuration and tell the world about it.
        std::cout << "pid:" << getpid() << std::endl;
        setConfig();

    }

    void shutdown()
    {
        BiddingAgent::shutdown();

        budgetController.shutdown();
    }

    /** Sets up an agent configuration for our example. */
    void setConfig()
    {
        config = AgentConfig();

        // Accounts are used to control the allocation of spending budgets for
        // an agent. The whole mechanism is fully generic and can be setup in
        // whatever you feel it bests suits you.
        config.account = {"hello", "world"};

        // Specify the properties of the creatives we are trying to show.
        config.creatives.push_back(Creative::sampleLB);
        config.creatives.push_back(Creative::sampleWS);
        config.creatives.push_back(Creative::sampleBB);
        config.creatives.push_back(Creative::sampleAA);
        config.creatives.push_back(Creative::sampleCC);
        config.creatives.push_back(Creative::sampleDD);
        config.creatives.push_back(Creative::sampleRR);
        config.creatives.push_back(Creative::sample1);
        config.creatives.push_back(Creative::sample2);
        config.creatives.push_back(Creative::sample3);
        config.creatives.push_back(Creative::sample4);

        config.providerConfig["appodeal"]["seat"] = 12;
      //  config.providerConfig["appodeal"]["iurl"] = "http://www.gnu.org";
        std::string mr = R"()";

        std::string s1 = R"()";

        std::string img = R"( )";

                for(auto & c: config.creatives){
                    c.providerConfig["appodeal"]["adm"] = mr + s1 + s2 + s3 + s4 + s5 +img;

                    std::string s = c.name;

                    c.providerConfig["appodeal"]["uniq_id"] = "world:" + s;

                    c.providerConfig["appodeal"]["nurl"] = "http://nurl.5kszypekn4.eu-west-1.elasticbeanstalk.com/?action=nurl&user=alex&auctionId=${AUCTION_ID}&bidRequestId=${AUCTION_ID}&impId=${AUCTION_IMP_ID}&winPrice=${AUCTION_PRICE}";

                    c.providerConfig["appodeal"]["iurl"] = "http://amadoad-dev.eu-west-1.elasticbeanstalk.com/_banners/a4/75/a4757c5908c8ed6805d23dd44c8d8098b2f7b28e.png";

                    c.providerConfig["appodeal"]["group_class"] = "group_class";

                }
        RTBKIT::AgentConfig::SegmentInfo gender;
	gender.include.add("F");
	gender.exclude.add("M");
        config.segments["gender"] = gender;

        // Indicate to the router that we want our bid requests to be augmented
        // with our frequency cap augmentor example.
        {
            AugmentationConfig augConfig;

            // Name of the requested augmentor.
            augConfig.name = "frequency-cap-ex";

            // If the augmentor was unable to augment our bid request then it
            // should be filtered before it makes it to our agent.
            augConfig.required = true;

            // Config parameter sent used by the augmentor to determine which
            // tag to set.
            augConfig.config = Json::Value(5);

            // Instruct to router to filter out all bid requests who have not
            // been tagged by our frequency cap augmentor.
            augConfig.filters.include.push_back("pass-frequency-cap-ex");

            config.addAugmentation(augConfig);
        }

        // Configures the agent to only receive 10% of the bid request traffic
        // that matches its filters.
        config.bidProbability = 0.7;

        // Tell the world about our config. We can change the configuration of
        // an agent at any time by calling this function.
        doConfig(config);

    }

    /** Simple fixed price bidding strategy. Note that the router is in charge
        of making sure we stay within budget and don't go bankrupt.
    */
    void bid(
            double timestamp,
            const Id & id,
            std::shared_ptr<RTBKIT::BidRequest> br,
            Bids bids,
            double timeLeftMs,
            const Json::Value & augmentations)
    {

        for (Bid& bid : bids) {

            // In our example, all our creatives are of the different sizes so
            // there should only ever be one biddable creative. Note that that
            // the router won't ask for bids on imp that don't have any
            // biddable creatives.
            ExcAssertGreaterEqual(bid.availableCreatives.size(), 1);
        /*    cerr << "-----" << endl;
            cerr << "size: " << bid.availableCreatives.size() << endl;

            for (auto& z : bid.availableCreatives) {

            cerr << "index:" << z << ";  spotindex: " << bid.spotIndex << endl;
            }
            cerr << "-----" << endl; */
            std::random_shuffle (  bid.availableCreatives.begin(),  bid.availableCreatives.end() );
            int availableCreative = bid.availableCreatives.front();

            // We don't really need it here but this is how you can get the
            // AdSpot and Creative object from the indexes.
            (void) br->imp[bid.spotIndex];

            (void) config.creatives[availableCreative];

            // Create a 0.0001$ CPM bid with our available creative.
            // Note that by default, the bid price is set to 0 which indicates
            // that we don't wish to bid on the given spot.
            bid.bid(availableCreative, MicroUSD(50));

        }

        // A value that will be passed back to us when we receive the result of
        // our bid.
        Json::Value metadata = 42;

        // Send our bid back to the agent.
        doBid(id, bids, metadata);

    }

    /** Simple pacing scheme which allocates 1$ to spend every period. */
    void pace()
    {
        // We need to register our account once with the banker service.
        if (!accountSetup) {
            accountSetup = true;
            budgetController.addAccountSync(config.account);
        }

        // Make sure we have 1$ to spend for the next period.
        budgetController.topupTransferSync(config.account, USD(1));
    }

    AgentConfig config;

    bool accountSetup;
    SlaveBudgetController budgetController;
};

} // namepsace RTBKIT

/******************************************************************************/
/* MAIN                                                                       */
/******************************************************************************/

int main(int argc, char** argv)
{
    using namespace boost::program_options;

    Datacratic::ServiceProxyArguments args;
    RTBKIT::SlaveBankerArguments bankerArgs;

    options_description options = args.makeProgramOptions();
    options.add_options()
        ("help,h", "Print this message");
    options.add(bankerArgs.makeProgramOptions());

    variables_map vm;
    store(command_line_parser(argc, argv).options(options).run(), vm);
    notify(vm);

    if (vm.count("help")) {
        cerr << options << endl;
        return 1;
    }

    auto serviceProxies = args.makeServiceProxies();
    RTBKIT::FixedPriceBiddingAgent agent(serviceProxies, "fixed-price-agent-ex");
    agent.init(bankerArgs.makeApplicationLayer(serviceProxies));
    agent.start();

    while (true) this_thread::sleep_for(chrono::seconds(10));

    // Won't ever reach this point but this is how you shutdown an agent.
    agent.shutdown();

    return 0;
}

<commit_msg>pre-production<commit_after>/** bidding_agent_ex.cc                                 -*- C++ -*-
    Rémi Attab, 22 Feb 2013
    Copyright (c) 2013 Datacratic.  All rights reserved.

    Example of a simple fixed-price bidding agent.

*/

#include "rtbkit/common/bids.h"
#include "rtbkit/core/banker/slave_banker.h"
#include "rtbkit/core/agent_configuration/agent_config.h"
#include "rtbkit/plugins/bidding_agent/bidding_agent.h"
#include "soa/service/service_utils.h"

#include <boost/program_options/cmdline.hpp>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/positional_options.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/variables_map.hpp>

#include <iostream>
#include <thread>
#include <chrono>
#include <string>     // std::string, std::to_string

using namespace std;
using namespace ML;

namespace RTBKIT {

/******************************************************************************/
/* FIXED PRICE BIDDING AGENT                                                  */
/******************************************************************************/

/** Simple bidding agent whose sole purpose in life is to bid 0.1$ CPM on every
    bid requests it sees. It also has a very simple pacer which ensures that we
    always have at most 1$ to spend every 10 seconds.

 */
struct FixedPriceBiddingAgent :
        public BiddingAgent
{
    FixedPriceBiddingAgent(
            std::shared_ptr<Datacratic::ServiceProxies> services,
            const string& serviceName) :
        BiddingAgent(services, serviceName),
        accountSetup(false)
    {}

    void init(const std::shared_ptr<ApplicationLayer> appLayer)
    {
        // We only want to specify a subset of the callbacks so turn the
        // annoying safety belt off.
        strictMode(false);

        onBidRequest = bind(
                &FixedPriceBiddingAgent::bid, this, _1, _2, _3, _4, _5, _6);

        // This component is used to speak with the master banker and pace the
        // rate at which we spend our budget.
        budgetController.setApplicationLayer(appLayer);
        budgetController.start();

        // Update our pacer every 10 seconds. Note that since this interacts
        // with the budgetController which is only synced up with the router
        // every few seconds, the wait period shouldn't be set too low.
        addPeriodic("FixedPriceBiddingAgent::pace", 10.0,
                [&] (uint64_t) { this->pace(); });

        BiddingAgent::init();

    }

    void start()
    {
        BiddingAgent::start();

        // Build our configuration and tell the world about it.
        std::cout << "pid:" << getpid() << std::endl;
        setConfig();

    }

    void shutdown()
    {
        BiddingAgent::shutdown();

        budgetController.shutdown();
    }

    /** Sets up an agent configuration for our example. */
    void setConfig()
    {
        config = AgentConfig();

        // Accounts are used to control the allocation of spending budgets for
        // an agent. The whole mechanism is fully generic and can be setup in
        // whatever you feel it bests suits you.
        config.account = {"hello", "world"};

        // Specify the properties of the creatives we are trying to show.
        config.creatives.push_back(Creative::sampleLB);
        config.creatives.push_back(Creative::sampleWS);
        config.creatives.push_back(Creative::sampleBB);
        config.creatives.push_back(Creative::sampleAA);
        config.creatives.push_back(Creative::sampleCC);
        config.creatives.push_back(Creative::sampleDD);
        config.creatives.push_back(Creative::sampleRR);
        config.creatives.push_back(Creative::sample1);
        config.creatives.push_back(Creative::sample2);
        config.creatives.push_back(Creative::sample3);
        config.creatives.push_back(Creative::sample4);

        config.providerConfig["appodeal"]["seat"] = 12;
      //  config.providerConfig["appodeal"]["iurl"] = "http://www.gnu.org";
        std::string mr = R"()";

        std::string s1 = R"()";

        std::string img = R"( )";

                for(auto & c: config.creatives){
                    c.providerConfig["appodeal"]["adm"] = mr + s1 + s2 + s3 + s4 + s5 +img;

                    std::string s = c.name;

                    c.providerConfig["appodeal"]["uniq_id"] = "world:" + s;

                    c.providerConfig["appodeal"]["nurl"] = "http://nurl.5kszypekn4.eu-west-1.elasticbeanstalk.com/?action=nurl&user=default&auctionId=${AUCTION_ID}&bidRequestId=${AUCTION_ID}&impId=${AUCTION_IMP_ID}&winPrice=${AUCTION_PRICE}";

                    c.providerConfig["appodeal"]["iurl"] = "http://amadoad-dev.eu-west-1.elasticbeanstalk.com/_banners/a4/75/a4757c5908c8ed6805d23dd44c8d8098b2f7b28e.png";

                    c.providerConfig["appodeal"]["group_class"] = "group_class";

                }
        RTBKIT::AgentConfig::SegmentInfo gender;
	gender.include.add("F");
	gender.exclude.add("M");
        config.segments["gender"] = gender;

        // Indicate to the router that we want our bid requests to be augmented
        // with our frequency cap augmentor example.
        {
            AugmentationConfig augConfig;

            // Name of the requested augmentor.
            augConfig.name = "frequency-cap-ex";

            // If the augmentor was unable to augment our bid request then it
            // should be filtered before it makes it to our agent.
            augConfig.required = true;

            // Config parameter sent used by the augmentor to determine which
            // tag to set.
            augConfig.config = Json::Value(5);

            // Instruct to router to filter out all bid requests who have not
            // been tagged by our frequency cap augmentor.
            augConfig.filters.include.push_back("pass-frequency-cap-ex");

            config.addAugmentation(augConfig);
        }

        // Configures the agent to only receive 10% of the bid request traffic
        // that matches its filters.
        config.bidProbability = 0.1;

        // Tell the world about our config. We can change the configuration of
        // an agent at any time by calling this function.
        doConfig(config);

    }

    /** Simple fixed price bidding strategy. Note that the router is in charge
        of making sure we stay within budget and don't go bankrupt.
    */
    void bid(
            double timestamp,
            const Id & id,
            std::shared_ptr<RTBKIT::BidRequest> br,
            Bids bids,
            double timeLeftMs,
            const Json::Value & augmentations)
    {

        for (Bid& bid : bids) {

            // In our example, all our creatives are of the different sizes so
            // there should only ever be one biddable creative. Note that that
            // the router won't ask for bids on imp that don't have any
            // biddable creatives.
            ExcAssertGreaterEqual(bid.availableCreatives.size(), 1);
        /*    cerr << "-----" << endl;
            cerr << "size: " << bid.availableCreatives.size() << endl;

            for (auto& z : bid.availableCreatives) {

            cerr << "index:" << z << ";  spotindex: " << bid.spotIndex << endl;
            }
            cerr << "-----" << endl; */
            std::random_shuffle (  bid.availableCreatives.begin(),  bid.availableCreatives.end() );
            int availableCreative = bid.availableCreatives.front();

            // We don't really need it here but this is how you can get the
            // AdSpot and Creative object from the indexes.
            (void) br->imp[bid.spotIndex];

            (void) config.creatives[availableCreative];

            // Create a 0.0001$ CPM bid with our available creative.
            // Note that by default, the bid price is set to 0 which indicates
            // that we don't wish to bid on the given spot.
            bid.bid(availableCreative, MicroUSD(50));

        }

        // A value that will be passed back to us when we receive the result of
        // our bid.
        Json::Value metadata = 42;

        // Send our bid back to the agent.
        doBid(id, bids, metadata);

    }

    /** Simple pacing scheme which allocates 1$ to spend every period. */
    void pace()
    {
        // We need to register our account once with the banker service.
        if (!accountSetup) {
            accountSetup = true;
            budgetController.addAccountSync(config.account);
        }

        // Make sure we have 1$ to spend for the next period.
        budgetController.topupTransferSync(config.account, USD(1));
    }

    AgentConfig config;

    bool accountSetup;
    SlaveBudgetController budgetController;
};

} // namepsace RTBKIT

/******************************************************************************/
/* MAIN                                                                       */
/******************************************************************************/

int main(int argc, char** argv)
{
    using namespace boost::program_options;

    Datacratic::ServiceProxyArguments args;
    RTBKIT::SlaveBankerArguments bankerArgs;

    options_description options = args.makeProgramOptions();
    options.add_options()
        ("help,h", "Print this message");
    options.add(bankerArgs.makeProgramOptions());

    variables_map vm;
    store(command_line_parser(argc, argv).options(options).run(), vm);
    notify(vm);

    if (vm.count("help")) {
        cerr << options << endl;
        return 1;
    }

    auto serviceProxies = args.makeServiceProxies();
    RTBKIT::FixedPriceBiddingAgent agent(serviceProxies, "fixed-price-agent-ex");
    agent.init(bankerArgs.makeApplicationLayer(serviceProxies));
    agent.start();

    while (true) this_thread::sleep_for(chrono::seconds(10));

    // Won't ever reach this point but this is how you shutdown an agent.
    agent.shutdown();

    return 0;
}

<|endoftext|>


<commit_before>/*
  Original code from tekkies/CVdrone (get actual address from github)

  Modified by Elliot Greenlee, Caleb Mennen, Jacob Pollack
  COSC 402 Senior Design

  Min Kao Drone Tour
  See readme at (get actual address from github)
*/

#include "ardrone/ardrone.h"
#include "objectFollowing/objectFollowing.h"
#include "manual/manual.h"
#include "lineFollowing/lineFollowing.h"
#include <iostream>
#include <vector>
#include <chrono>
#include <thread>

using namespace std;

int main(int argc, char *argv[])
{
  //AR.Drone class
  ARDrone ardrone;

  //Display variables

  char modeDisplay[80]; //print buffer for flying mode
  char flyingDisplay[80]; //print buffer for if flying
  char speedDisplay[80]; //print buffer for speed

  cv::Scalar green = CV_RGB(0,255,0); //putText color value

  //Drone control
  bool learnMode = false;

  float speed = 0.0;
  double vx = 0.0;
  double vy = 0.0;
  double vz = 0.0;
  double vr = 0.0;

  enum FlyingMode {
    Manual,
    ObjectFollowing,
    LineFollowing
  };

  FlyingMode flyingMode = Manual;

<<<<<<< HEAD
=======
  //Object Following variables
>>>>>>> 59c87e279adc9e413704a5abceb2389db97072c3
  int minH = 0, maxH = 255;
  int minS = 0, maxS = 255;
  int minV = 0, maxV = 255;
  int rect_area = 0;
  bool moveStatus = false;
  const char *moveStatuses[2] = {"STOP", "GO"};
  float heading = 0;
  cv::Rect rect;

  //Initializing Message
  printf("Connecting to the drone\n");
  printf("If there is no version number response in the next 10 seconds, please restart the drone and code.\n");
  printf("To disconnect, press the ESC key\n\n");
  fflush(stdout);

  // Initialize
  if (!ardrone.open()) {
    printf("Failed to initialize.\n");
    return -1;
  }

  cv::KalmanFilter kalman(4, 2, 0);

  //Open and read Thresholds file for object following hsv values
  //Create a window for object following hsv and binalization
  initializeObjectFollowing(&kalman, &maxH, &minH, &maxS, &minS, &maxV, &minV);

  //Print default command information
  printf("Currently the drone is in manual mode.\n");
  printf("Use the b key for manual mode, the n key for object following, and the m key for line following. The number keys can be used to set a speed. Use spacebar to take off and land, which is required before any control can be executed.\n\n");

  FILE *flight_log;
  flight_log = fopen("flight_log.txt", "w");

  // Main loop
  while (1) {
    speed = 0.0;
    // Key input
    int key = cv::waitKey(33);

    //press the escape key to exit
    if (key == 0x1b) {
      break;
    }

    //switch between learning and non-learning mode
    if (key == 'l') {
      learnMode = !learnMode;
      if (learnMode) {
        printf("Learning mode is enabled\n");
        printf("The color at the crosshairs is being learned\n");
        printf("Press l again to turn off learning mode\n\n");
      }
      else {
        printf("Learning mode is disabled\n");
        printf("The color last at the crosshairs will be targeted\n");
        printf("Press l again to learn a different color\n\n");
      }
    }

    //switch between flying modes
    if (key == 'b') {
      flyingMode = Manual;
      //TODO: Allow user to set camera mode in Manual
      //TODO: Change 0/1 to CONSTANTS of 0 = front, 1 = bottom
      ardrone.setCamera(0);
      printf("Manual flying mode is enabled\n");
      printf("Press n for object following and m for line following\n");
      printf("While in manual mode, use q and a for up and down, t and g for forward and backward, and f and h for left and right. Press space to take off.\n\n");
    }
    else if (key == 'n') {
      flyingMode = ObjectFollowing;
      ardrone.setCamera(0);
      printf("Object Following flying mode is enabled\n");
      printf("Press b for manual and m for line following\n");
      printf("While in object following mode, use l to toggle learning a specific color. Press space to take off after learning a color.\n\n");
    }
    else if (key == 'm') {
      flyingMode = LineFollowing;
      ardrone.setCamera(1);
      printf("Line Following flying mode is enabled\n");
      printf("Press b for manual and n for object following\n");
      printf("No control for line following yet exists\n\n");
    }

    // Get an image
    cv::Mat image = ardrone.getImage();

   /* //TODO: Move object following image stuff to a new file
    // HSV image
    cv::Mat hsv;
    cv::cvtColor(image, hsv, cv::COLOR_BGR2HSV_FULL);

    // Binalize
    cv::Mat binalized;
    cv::Scalar lower(minH, minS, minV);
    cv::Scalar upper(maxH, maxS, maxV);
    cv::inRange(hsv, lower, upper, binalized);

    // Show result
    cv::imshow("binalized", binalized);

    // De-noising
    cv::Mat kernel = getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
    cv::morphologyEx(binalized, binalized, cv::MORPH_CLOSE, kernel);

    // Detect contours
    vector<vector<cv::Point> > contours;
    cv::findContours(binalized.clone(), contours, cv::RETR_CCOMP, cv::CHAIN_APPROX_SIMPLE);

    // Find largest contour
    int contour_index = -1;
    double max_area = 0.0;
    for (size_t i = 0; i < contours.size(); i++) {
      double area = fabs(cv::contourArea(contours[i]));
      if (area > max_area) {
        contour_index = i;
        max_area = area;
      }
    }

    cv::Rect rect;

    // Object detected
    if (contour_index >= 0) {
      // Moments
      cv::Moments moments = cv::moments(contours[contour_index], true);
      double marker_y = (int)(moments.m01 / moments.m00);
      double marker_x = (int)(moments.m10 / moments.m00);

      // Measurements
      cv::Mat measurement = (cv::Mat1f(2, 1) << marker_x, marker_y);

      // Correction
      cv::Mat estimated = kalman.correct(measurement);

      // Show result
      rect = cv::boundingRect(contours[contour_index]);
      cv::rectangle(image, rect, cv::Scalar(0, 255, 0));
    }

    // Prediction
    cv::Mat1f prediction = kalman.predict();
    int radius = 1e+3 * kalman.errorCovPre.at<float>(0, 0);

    // Calculate object heading fraction
    float heading = -((image.cols/2) - prediction(0, 0))/(image.cols/2);
  */

    //Speed
    if ((key >= '0') && (key <= '9')) //number keys
    {
      speed = (key-'0')*0.1;
    }

    //Write speed to image
    sprintf(speedDisplay, "Speed = %3.2f", speed);
    putText(image, speedDisplay, cvPoint(30,40), cv::FONT_HERSHEY_COMPLEX_SMALL, 0.8, green, 1, CV_AA);

    //Take off / Landing
    if (key == ' ') { //spacebar
      if (ardrone.onGround()) {
        ardrone.takeoff();
	fprintf(flight_log, "TAKEOFF\n");
        std::this_thread::sleep_for(std::chrono::milliseconds(5000));
      }
      else {
        ardrone.landing();
	fprintf(flight_log, "LAND\n");
      }
    }

    //Write if grounded or flying to image
    if (ardrone.onGround()) {
      sprintf(flyingDisplay, "Landed");
    }
    else {
      sprintf(flyingDisplay, "Flying");
    }
    putText(image, flyingDisplay, cvPoint(200,40), cv::FONT_HERSHEY_COMPLEX_SMALL, 0.8, green, 1, CV_AA);

    switch (flyingMode) {
      case Manual:
        //TODO: Scale these values for normal human control when in manual mode
        vx = 0;
        vy = 0;
        vz = 0;
        vr = 0;
        if (key == 't') { vx =  1.0; } //t key
        if (key == 'g') { vx = -1.0; } //g key
        if (key == 'f') { vy =  1.0; } //f key
        if (key == 'h') { vy = -1.0; } //h key
        if (key == 'q') { vz =  1.0; } //q key
        if (key == 'a') { vz = -1.0; } //a key
        //TODO: Verify if these vr values should be negative
        if (key == 'r') { vr =  1.0; } //r key
        if (key == 'y') { vr = -1.0; } //y key

        sprintf(modeDisplay, "Manual Mode");
        displayManualInfo(&image, vx, vy, vz, vr);
        break;

      case ObjectFollowing:
        heading = detectObject(image, kalman, minH, maxH, minS, maxS, minV, maxV, learnMode, moveStatus, &rect);
       /* // Sample the object color
        if(learnMode) {
          // Show targeting crosshairs
          cv::line(image, cvPoint(image.cols/2, 0), cvPoint(image.cols/2, image.rows/2 - 2), green); //top vertical crosshair
          cv::line(image, cvPoint(image.cols/2, image.rows/2 + 2), cvPoint(image.cols/2, image.rows), green); //bottom vertical crosshair
          cv::line(image, cvPoint(0, image.rows/2), cvPoint(image.cols/2 - 2, image.rows/2), green); //left horizontal crosshair
          cv::line(image, cvPoint(image.cols/2 + 2, image.rows/2), cvPoint(image.cols, image.rows/2), green); //right horizontal crosshair

          hsvSample = hsv.at<cv::Vec3b>(cvPoint(image.cols/2, image.rows/2));

          setHSVTrackBarPositions(hsvSample[0], hsvSample[1], hsvSample[2], tolerance);
        }
      */

        rect_area = rect.width * rect.height;

        //Execute drone movement

        //printf("rect.width: %d, rect.height: %d, rect.area: %d mode: %d\n", rect.width, rect.height, rect_area, flyingMode);

        if (rect_area > 10000) {
          speed = -0.2;
          vx = 0;

          moveStatus = false;
        }
        else {
          moveStatus = true;
        }

        vx = speed;
        vr = -heading;

        sprintf(modeDisplay, "Object Following Mode");
        break;

      case LineFollowing:
        sprintf(modeDisplay, "Line Following Mode");
        break;
    }

    putText(image, modeDisplay, cvPoint(30,20), cv::FONT_HERSHEY_COMPLEX_SMALL, 0.8, green, 1, CV_AA);

    fprintf(flight_log, "%s ardrone.move3D(vx=%f, vy=%f, vz=%f, vr=%f) || rect_area = %d\n",
        moveStatuses[moveStatus], (speed), (vy * speed), (vz * speed), vr, rect_area);

    ardrone.move3D(speed, vy * speed, vz * speed, vr);

    //Display the camera feed
    cv::imshow("camera", image);
  }

  //Write hsv values to a file
  closeObjectFollowing(maxH, minH, maxS, minS, maxV, minV);
  //TODO: create close manual and close line following functions

  //Close connection to drone
  ardrone.close();

  return 0;
}

<commit_msg>Remove commented out sections from last refactor.<commit_after>/*
  Original code from tekkies/CVdrone (get actual address from github)

  Modified by Elliot Greenlee, Caleb Mennen, Jacob Pollack
  COSC 402 Senior Design

  Min Kao Drone Tour
  See readme at (get actual address from github)
*/

#include "ardrone/ardrone.h"
#include "objectFollowing/objectFollowing.h"
#include "manual/manual.h"
#include "lineFollowing/lineFollowing.h"
#include <iostream>
#include <vector>
#include <chrono>
#include <thread>

using namespace std;

int main(int argc, char *argv[])
{
  //AR.Drone class
  ARDrone ardrone;

  //Display variables

  char modeDisplay[80]; //print buffer for flying mode
  char flyingDisplay[80]; //print buffer for if flying
  char speedDisplay[80]; //print buffer for speed

  cv::Scalar green = CV_RGB(0,255,0); //putText color value

  //Drone control
  bool learnMode = false;

  float speed = 0.0;
  double vx = 0.0;
  double vy = 0.0;
  double vz = 0.0;
  double vr = 0.0;

  enum FlyingMode {
    Manual,
    ObjectFollowing,
    LineFollowing
  };

  FlyingMode flyingMode = Manual;

  //Object Following variables
  int minH = 0, maxH = 255;
  int minS = 0, maxS = 255;
  int minV = 0, maxV = 255;
  int rect_area = 0;
  bool moveStatus = false;
  const char *moveStatuses[2] = {"STOP", "GO"};
  float heading = 0;
  cv::Rect rect;

  //Initializing Message
  printf("Connecting to the drone\n");
  printf("If there is no version number response in the next 10 seconds, please restart the drone and code.\n");
  printf("To disconnect, press the ESC key\n\n");
  fflush(stdout);

  // Initialize
  if (!ardrone.open()) {
    printf("Failed to initialize.\n");
    return -1;
  }

  cv::KalmanFilter kalman(4, 2, 0);

  //Open and read Thresholds file for object following hsv values
  //Create a window for object following hsv and binalization
  initializeObjectFollowing(&kalman, &maxH, &minH, &maxS, &minS, &maxV, &minV);

  //Print default command information
  printf("Currently the drone is in manual mode.\n");
  printf("Use the b key for manual mode, the n key for object following, and the m key for line following. The number keys can be used to set a speed. Use spacebar to take off and land, which is required before any control can be executed.\n\n");

  FILE *flight_log;
  flight_log = fopen("flight_log.txt", "w");

  // Main loop
  while (1) {
    speed = 0.0;
    // Key input
    int key = cv::waitKey(33);

    //press the escape key to exit
    if (key == 0x1b) {
      break;
    }

    //switch between learning and non-learning mode
    if (key == 'l') {
      learnMode = !learnMode;
      if (learnMode) {
        printf("Learning mode is enabled\n");
        printf("The color at the crosshairs is being learned\n");
        printf("Press l again to turn off learning mode\n\n");
      }
      else {
        printf("Learning mode is disabled\n");
        printf("The color last at the crosshairs will be targeted\n");
        printf("Press l again to learn a different color\n\n");
      }
    }

    //switch between flying modes
    if (key == 'b') {
      flyingMode = Manual;
      //TODO: Allow user to set camera mode in Manual
      //TODO: Change 0/1 to CONSTANTS of 0 = front, 1 = bottom
      ardrone.setCamera(0);
      printf("Manual flying mode is enabled\n");
      printf("Press n for object following and m for line following\n");
      printf("While in manual mode, use q and a for up and down, t and g for forward and backward, and f and h for left and right. Press space to take off.\n\n");
    }
    else if (key == 'n') {
      flyingMode = ObjectFollowing;
      ardrone.setCamera(0);
      printf("Object Following flying mode is enabled\n");
      printf("Press b for manual and m for line following\n");
      printf("While in object following mode, use l to toggle learning a specific color. Press space to take off after learning a color.\n\n");
    }
    else if (key == 'm') {
      flyingMode = LineFollowing;
      ardrone.setCamera(1);
      printf("Line Following flying mode is enabled\n");
      printf("Press b for manual and n for object following\n");
      printf("No control for line following yet exists\n\n");
    }

    // Get an image
    cv::Mat image = ardrone.getImage();

    //Speed
    if ((key >= '0') && (key <= '9')) //number keys
    {
      speed = (key-'0')*0.1;
    }

    //Write speed to image
    sprintf(speedDisplay, "Speed = %3.2f", speed);
    putText(image, speedDisplay, cvPoint(30,40), cv::FONT_HERSHEY_COMPLEX_SMALL, 0.8, green, 1, CV_AA);

    //Take off / Landing
    if (key == ' ') { //spacebar
      if (ardrone.onGround()) {
        ardrone.takeoff();
	fprintf(flight_log, "TAKEOFF\n");
        std::this_thread::sleep_for(std::chrono::milliseconds(5000));
      }
      else {
        ardrone.landing();
	fprintf(flight_log, "LAND\n");
      }
    }

    //Write if grounded or flying to image
    if (ardrone.onGround()) {
      sprintf(flyingDisplay, "Landed");
    }
    else {
      sprintf(flyingDisplay, "Flying");
    }
    putText(image, flyingDisplay, cvPoint(200,40), cv::FONT_HERSHEY_COMPLEX_SMALL, 0.8, green, 1, CV_AA);

    switch (flyingMode) {
      case Manual:
        //TODO: Scale these values for normal human control when in manual mode
        vx = 0;
        vy = 0;
        vz = 0;
        vr = 0;
        if (key == 't') { vx =  1.0; } //t key
        if (key == 'g') { vx = -1.0; } //g key
        if (key == 'f') { vy =  1.0; } //f key
        if (key == 'h') { vy = -1.0; } //h key
        if (key == 'q') { vz =  1.0; } //q key
        if (key == 'a') { vz = -1.0; } //a key
        //TODO: Verify if these vr values should be negative
        if (key == 'r') { vr =  1.0; } //r key
        if (key == 'y') { vr = -1.0; } //y key

        sprintf(modeDisplay, "Manual Mode");
        displayManualInfo(&image, vx, vy, vz, vr);
        break;

      case ObjectFollowing:
        heading = detectObject(image, kalman, minH, maxH, minS, maxS, minV, maxV, learnMode, moveStatus, &rect);

        rect_area = rect.width * rect.height;

        //Execute drone movement

        //printf("rect.width: %d, rect.height: %d, rect.area: %d mode: %d\n", rect.width, rect.height, rect_area, flyingMode);

        if (rect_area > 10000) {
          speed = -0.2;
          vx = 0;

          moveStatus = false;
        }
        else {
          moveStatus = true;
        }

        vx = speed;
        vr = -heading;

        sprintf(modeDisplay, "Object Following Mode");
        break;

      case LineFollowing:
        sprintf(modeDisplay, "Line Following Mode");
        break;
    }

    putText(image, modeDisplay, cvPoint(30,20), cv::FONT_HERSHEY_COMPLEX_SMALL, 0.8, green, 1, CV_AA);

    fprintf(flight_log, "%s ardrone.move3D(vx=%f, vy=%f, vz=%f, vr=%f) || rect_area = %d\n",
        moveStatuses[moveStatus], (speed), (vy * speed), (vz * speed), vr, rect_area);

    ardrone.move3D(speed, vy * speed, vz * speed, vr);

    //Display the camera feed
    cv::imshow("camera", image);
  }

  //Write hsv values to a file
  closeObjectFollowing(maxH, minH, maxS, minS, maxV, minV);
  //TODO: create close manual and close line following functions

  //Close connection to drone
  ardrone.close();

  return 0;
}

<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "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 Nokia Corporation and its Subsidiary(-ies) 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."
** $QT_END_LICENSE$
**
****************************************************************************/

#include "tennis.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    Tennis d;
    QObject::connect(&d, SIGNAL(accepted()), &app, SLOT(quit()));

#if defined(Q_WS_MAEMO_6)
    d.showFullScreen();
#else
    d.show();
#endif

    app.exec();

    return 0;
}

<commit_msg>Made bttennis fullscreen on symbian<commit_after>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "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 Nokia Corporation and its Subsidiary(-ies) 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."
** $QT_END_LICENSE$
**
****************************************************************************/

#include "tennis.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    Tennis d;
    QObject::connect(&d, SIGNAL(accepted()), &app, SLOT(quit()));

#if defined(Q_WS_MAEMO_6) || defined(Q_OS_SYMBIAN)
    d.showFullScreen();
#else
    d.show();
#endif

    app.exec();

    return 0;
}

<|endoftext|>


<commit_before>#include<iostream>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
using namespace std;

class acc {
    private:
        long int accnum1;
        string pswd1;
        int cash1;
    public:
        void get_data();
        void display_data(); //only for debugging

get_data() {

        //INput cash nad password from user
        cout<<"Enter cash to deposit initially (min 500):";
        cin>>cash1;
        cout<<"Enter your account password:";
        cin>>pswd1;

        //Generating account no
        ifstream f;
        f.open("Acc_no.txt",ios::in);
        int i;
        f>>accnum1;
        accnum1++;
        f.close();

        //Outputting account number
        ofstream f1;
        f1.open("Acc_no.txt",ios::out);
        f1 << accnum1;
        f1.close();

        cout << "Account no generated:" << accnum1 << endl;

        cout << "Account created successfully";
    }

display_data() {
    ifstream f2;
    f2.open("bankaccounts.txt",ios::in);

    while(f2.read((char*)&n,sizeof(n))){   //f2.read((char*)&n,sizeof(n));
        cout<<endl<<"Account number:"<<n.accnum1<<" ";
        cout<<"Cash in account:"<<n.cash1;
        }
    f2.close();

    }

}n;

void newAccount();
void editAccount(int, string);

void admin(int, string);
void client(int, string);

char name[256];

int main() {

    //Welcome Screen
    cout << "Hello and Welcome to E- Manager" << endl;
    cout << "Please enter your name below" << endl;

    //Inputting user's name to greet the user.

    cin.getline (name,256);
    cout << "Good day to you, " << name << endl;
    printf("\n");

    //Start banking functions
    again:
    cout << "Enter any of the numbers go ahead" << endl;
    cout << "What would you like to do from the following options:" << endl;
    cout << "1. Create new account" << endl;
    cout << "2. Edit existing account" << endl;
    cout << "3. Exit" << endl;

    //Choose options
    int choice;
    int accnum;
    string pswd;
    cin >> choice;
    printf("\n");

    //Use of switch for any one of the options
    switch(choice) {

        //Case to create new account
        case 1:
            newAccount();
            break;

        //Case to edit existing account
        case 2:
            cout << "Enter the account number: " << endl;
            cin >> accnum;

            //Default account number set up.
            if(accnum == 123456) {
                wrongpswd:
                cout << "Enter your account's password" << endl;
                cin >> pswd;
                if (pswd == "nitk2015") {
                    printf("\n");
                    editAccount(accnum,pswd);
                    }
                else {
                    cout << "Wrong Password entered" << endl;
                    cout << "Try again" << endl;
                    printf("\n");
                    goto wrongpswd;
                    }
                }

            //In case account number doesn't match with the file
            else {
                cout << "Account not found. Create a new account" << endl;
                goto again;
                }
            break;

        //Case to exit the program
        case 3:
            exit(0);

        //In case none of the options are entered
        default:
            cout << "Enter an appropriate choice" << endl;
            goto again;
    }

    return 0;
}

//Function to add new account
void newAccount()
{
        cout<<"*** Welcome to new account creation ***";
        n.get_data();
        ofstream f;
        f.open("bankaccounts.txt",ios::app);
        f.write((char*)&n,sizeof(n));
        f.close();
        n.display_data(); //Only for debugging

}

//Function to edit existing account
void editAccount(int accnum, string pswd) {

    again1;
    //Account access options
    cout << "Enter the number corresponding to ";
    cout << "one of the following options" << endl;
    cout << "1. Admin access" << endl;
    cout << "2. Client access" << endl;

    int choice;
    cin >> choice;

    switch(choice) {

        //Admin access option
        case 1:
            cout << "You have chosen admin access for your account" << endl;
            admin(accnum, pswd);
            break;
        //Client access option
        case 2:
            cout << "You have chosen client access for your account" << endl;
            client(accnum ,pswd);
            break;
        //None of the above options
        default:
            cout << "Please select a valid option" << endl;
            goto again1;

        }
}

//Function to give admin access over an account
void admin(int accnum, string pswd) {

    again2:
    cout << "Welcome " << name << " to your account number " << accnum << endl;
    cout << "Select any one of the following options" << endl;
    cout << "1. View Account Details" << endl;
    cout << "2. Add Money to Account" << endl;
    cout << "3. Remove Money from Account" << endl;
    cout << "4. Exit" << endl;

    int n;
    cin >> n;

    switch (n) {

        //Account Viewing
        case 1:
            cout << "Here are the details of your account" << endl;
            //Add code to show Account Details

            break;

        //Account money addition
        case 2:
            cout << "Here are the details of your account" << endl;
            //Add code to show Account Details

            //Add code to add money to the account
            int addmoney;
            cout << "Enter the amount of money to add to your account" << endl;
            cin >> addmoney;

            break;

        //Account money withdrawal
        case 3:
            cout << "Here are the details of your account" << endl;
            //Add code to show Account Details

            //Add code to subtract money from account
            int submoney;
            cout << "Enter the amount of money to be removed from your account" << endl;
            cin >> submoney;

            break;

        //Exit statement
        case 4:
            exit(0);

        //None of the above options
        default:
            cout << "Please select a valid option" << endl;
            goto again2;
    }

}

//Function to give client access over an account
void client(int accnum, string pswd) {
    again3:
    cout << "Welcome " << name << " to your account number" << endl;
    cout << "Select any one of the following options" << endl;
    cout << "1. View Account Details" << endl;
    cout << "2. Add spending to Account" << endl;
    cout << "3. Exit" << endl;

    int n;
    cin >> n;

    switch(n) {

        //Account Viewing
        case 1:
            cout << "Here are the details of your account" << endl;
            //Add code to show Account Details

            break;

        //Account spending
        case 2:
            cout << "Here are the details of your account" << endl;
            //Add code to show Account Details

            //Add code to spend money from account
            int spendmoney;
            cout << "Enter the amount of money to be spent from your account" << endl;
            cin >> spendmoney;

            break;

        //Exit from account
        case 3:
            exit(0);

        //None of the above options
        default:
            cout << "Please select a valid option" << endl;
            goto again3;
    }
}
<commit_msg>Main function size reduced<commit_after>#include<iostream>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
using namespace std;

class acc {
    private:
        long int accnum1;
        string pswd1;
        int cash1;
    public:
        void get_data();
        void display_data(); //only for debugging

get_data() {

        //Input cash nad password from user
        cout<<"Enter cash to deposit initially (min 500):";
        cin>>cash1;
        cout<<"Enter your account password:";
        cin>>pswd1;

        //Generating account no
        ifstream f;
        f.open("Acc_no.txt",ios::in);
        int i;
        f>>accnum1;
        accnum1++;
        f.close();

        //Outputting account number
        ofstream f1;
        f1.open("Acc_no.txt",ios::out);
        f1 << accnum1;
        f1.close();

        cout << "Account no generated:" << accnum1 << endl;

        cout << "Account created successfully";
    }

display_data() {
    ifstream f2;
    f2.open("bankaccounts.txt",ios::in);

    while(f2.read((char*)&n,sizeof(n))){   //f2.read((char*)&n,sizeof(n));
        cout<<endl<<"Account number:"<<n.accnum1<<" ";
        cout<<"Cash in account:"<<n.cash1;
        }
    f2.close();

    }

}n;

void newAccount();
void editAccount(int, string);

void admin(int, string);
void client(int, string);

char name[256];

void welcome();
void bank_display();

void bank_functions(int);

int main() {

    welcome();

    //Inputting user's name to greet the user.

    cin.getline (name,256);
    cout << "Good day to you, " << name << endl;
    printf("\n");

    //Start banking functions
    bank_display();

    //Choose options
    int choice;
    int accnum;
    string pswd;
    cin >> choice;
    printf("\n");

    bank_functions(choice)

    }

    return 0;
}

void welcome() {
    //Welcome Screen
    cout << "Hello and Welcome to E- Manager" << endl;
    cout << "Please enter your name below" << endl;
}

void bank_display() {
    cout << "Enter any of the numbers go ahead" << endl;
    cout << "What would you like to do from the following options:" << endl;
    cout << "1. Create new account" << endl;
    cout << "2. Edit existing account" << endl;
    cout << "3. Exit" << endl;

}

void bank_functions(int choice) {
    //Use of switch for any one of the options
    switch(choice) {

        //Case to create new account
        case 1:
            newAccount();
            break;

        //Case to edit existing account
        case 2:
            cout << "Enter the account number: " << endl;
            cin >> accnum;

            //Default account number set up.
            if(accnum == 123456) {
                wrongpswd:
                cout << "Enter your account's password" << endl;
                cin >> pswd;
                if (pswd == "nitk2015") {
                    printf("\n");
                    editAccount(accnum,pswd);
                    }
                else {
                    cout << "Wrong Password entered" << endl;
                    cout << "Try again" << endl;
                    printf("\n");
                    goto wrongpswd;
                    }
                }

            //In case account number doesn't match with the file
            else {
                cout << "Account not found. Create a new account" << endl;
                }
            break;

        //Case to exit the program
        case 3:
            exit(0);
    }

}

//Function to add new account
void newAccount() {
        cout<<"*** Welcome to new account creation ***";
        n.get_data();
        ofstream f;
        f.open("bankaccounts.txt",ios::app);
        f.write((char*)&n,sizeof(n));
        f.close();
        n.display_data(); //Only for debugging

}

//Function to edit existing account
void editAccount(int accnum, string pswd) {

    again1;
    //Account access options
    cout << "Enter the number corresponding to ";
    cout << "one of the following options" << endl;
    cout << "1. Admin access" << endl;
    cout << "2. Client access" << endl;

    int choice;
    cin >> choice;

    switch(choice) {

        //Admin access option
        case 1:
            cout << "You have chosen admin access for your account" << endl;
            admin(accnum, pswd);
            break;
        //Client access option
        case 2:
            cout << "You have chosen client access for your account" << endl;
            client(accnum ,pswd);
            break;
        //None of the above options
        default:
            cout << "Please select a valid option" << endl;
            goto again1;

        }
}

//Function to give admin access over an account
void admin(int accnum, string pswd) {

    again2:
    cout << "Welcome " << name << " to your account number " << accnum << endl;
    cout << "Select any one of the following options" << endl;
    cout << "1. View Account Details" << endl;
    cout << "2. Add Money to Account" << endl;
    cout << "3. Remove Money from Account" << endl;
    cout << "4. Exit" << endl;

    int n;
    cin >> n;

    switch (n) {

        //Account Viewing
        case 1:
            cout << "Here are the details of your account" << endl;
            //Add code to show Account Details

            break;

        //Account money addition
        case 2:
            cout << "Here are the details of your account" << endl;
            //Add code to show Account Details

            //Add code to add money to the account
            int addmoney;
            cout << "Enter the amount of money to add to your account" << endl;
            cin >> addmoney;

            break;

        //Account money withdrawal
        case 3:
            cout << "Here are the details of your account" << endl;
            //Add code to show Account Details

            //Add code to subtract money from account
            int submoney;
            cout << "Enter the amount of money to be removed from your account" << endl;
            cin >> submoney;

            break;

        //Exit statement
        case 4:
            exit(0);

        //None of the above options
        default:
            cout << "Please select a valid option" << endl;
            goto again2;
    }

}

//Function to give client access over an account
void client(int accnum, string pswd) {
    again3:
    cout << "Welcome " << name << " to your account number" << endl;
    cout << "Select any one of the following options" << endl;
    cout << "1. View Account Details" << endl;
    cout << "2. Add spending to Account" << endl;
    cout << "3. Exit" << endl;

    int n;
    cin >> n;

    switch(n) {

        //Account Viewing
        case 1:
            cout << "Here are the details of your account" << endl;
            //Add code to show Account Details

            break;

        //Account spending
        case 2:
            cout << "Here are the details of your account" << endl;
            //Add code to show Account Details

            //Add code to spend money from account
            int spendmoney;
            cout << "Enter the amount of money to be spent from your account" << endl;
            cin >> spendmoney;

            break;

        //Exit from account
        case 3:
            exit(0);

        //None of the above options
        default:
            cout << "Please select a valid option" << endl;
            goto again3;
    }
}
<|endoftext|>


<commit_before>// Scintilla source code edit control
/** @file LexEiffel.cxx
 ** Lexer for Eiffel.
 **/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <fcntl.h>

#include "Platform.h"

#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"

inline bool isEiffelOperator(char ch) {
	// '.' left out as it is used to make up numbers
	return ch == '*' || ch == '/' || ch == '\\' || ch == '-' || ch == '+' ||
	        ch == '(' || ch == ')' || ch == '=' ||
	        ch == '{' || ch == '}' || ch == '~' ||
	        ch == '[' || ch == ']' || ch == ';' ||
	        ch == '<' || ch == '>' || ch == ',' ||
	        ch == '.' || ch == '^' || ch == '%' || ch == ':' ||
		ch == '!' || ch == '@' || ch == '?';
}

static void getRangeLowered(unsigned int start,
		unsigned int end,
		Accessor &styler,
		char *s,
		unsigned int len) {
	unsigned int i = 0;
	while ((i < end - start + 1) && (i < len-1)) {
		s[i] = static_cast<char>(tolower(styler[start + i]));
		i++;
	}
	s[i] = '\0';
}

class LexContext {
	Accessor &styler;
	int lengthDoc;
	int currentPos;
	LexContext& operator=(const LexContext&) {
		return *this;
	}
public:
	int state;
	char ch;
	char chNext;

	LexContext(unsigned int startPos, int length,
                        int initStyle, Accessor &styler_) :
		styler(styler_),
		lengthDoc(startPos + length),
		currentPos(startPos),
		state(initStyle),
		ch(0),
		chNext(0) {
		styler.StartAt(startPos);
		styler.StartSegment(startPos);
		ch = styler.SafeGetCharAt(currentPos);
		chNext = styler.SafeGetCharAt(currentPos+1);
	}
	void Complete() {
		styler.ColourTo(currentPos - 1, state);
	}
	bool More() {
		return currentPos <= lengthDoc;
	}
	void Forward() {
		currentPos++;
		ch = chNext;
		chNext = styler.SafeGetCharAt(currentPos + 1);
		if (styler.IsLeadByte(ch)) {
			currentPos++;
			ch = chNext;
			chNext = styler.SafeGetCharAt(currentPos + 1);
		}
	}
	void ChangeState(int state_) {
		state = state_;
	}
	void SetState(int state_) {
		styler.ColourTo(currentPos - 1, state);
		state = state_;
	}
	void GetCurrentLowered(char *s, int len) {
		getRangeLowered(styler.GetStartSegment(), currentPos - 1, styler, s, len);
	}
};

static void ColouriseEiffelDoc(unsigned int startPos,
                            int length,
                            int initStyle,
                            WordList *keywordlists[],
                            Accessor &styler) {

	WordList &keywords = *keywordlists[0];

	LexContext lc(startPos, length, initStyle, styler);

	for (; lc.More(); lc.Forward()) {

		if (lc.state == SCE_EIFFEL_STRINGEOL) {
			if (lc.ch != '\r' && lc.ch != '\n') {
				lc.SetState(SCE_EIFFEL_DEFAULT);
			}
		} else if (lc.state == SCE_EIFFEL_OPERATOR) {
			lc.SetState(SCE_EIFFEL_DEFAULT);
		} else if (lc.state == SCE_EIFFEL_WORD) {
			if (!iswordchar(lc.ch)) {
				char s[100];
				lc.GetCurrentLowered(s, sizeof(s));
				if (!keywords.InList(s)) {
					lc.ChangeState(SCE_EIFFEL_IDENTIFIER);
				}
				lc.SetState(SCE_EIFFEL_DEFAULT);
			}
		} else if (lc.state == SCE_EIFFEL_NUMBER) {
			if (!iswordchar(lc.ch)) {
				lc.SetState(SCE_EIFFEL_DEFAULT);
			}
		} else if (lc.state == SCE_EIFFEL_COMMENTLINE) {
			if (lc.ch == '\r' || lc.ch == '\n') {
				lc.SetState(SCE_EIFFEL_DEFAULT);
			}
		} else if (lc.state == SCE_EIFFEL_STRING) {
			if (lc.ch == '%') {
				lc.Forward();
			} else if (lc.ch == '\"') {
				lc.Forward();
				lc.SetState(SCE_EIFFEL_DEFAULT);
			}
		} else if (lc.state == SCE_EIFFEL_CHARACTER) {
			if (lc.ch == '\r' || lc.ch == '\n') {
				lc.SetState(SCE_EIFFEL_STRINGEOL);
			} else if (lc.ch == '%') {
				lc.Forward();
			} else if (lc.ch == '\'') {
				lc.Forward();
				lc.SetState(SCE_EIFFEL_DEFAULT);
			}
		}

		if (lc.state == SCE_EIFFEL_DEFAULT) {
			if (lc.ch == '-' && lc.chNext == '-') {
				lc.SetState(SCE_EIFFEL_COMMENTLINE);
			} else if (lc.ch == '\"') {
				lc.SetState(SCE_EIFFEL_STRING);
			} else if (lc.ch == '\'') {
				lc.SetState(SCE_EIFFEL_CHARACTER);
			} else if (isdigit(lc.ch) || (lc.ch == '.')) {
				lc.SetState(SCE_EIFFEL_NUMBER);
			} else if (iswordstart(lc.ch)) {
				lc.SetState(SCE_EIFFEL_WORD);
			} else if (isEiffelOperator(lc.ch)) {
				lc.SetState(SCE_EIFFEL_OPERATOR);
			}
		}
	}
	lc.Complete();
}

static bool IsEiffelComment(Accessor &styler, int pos, int len) {
	return len>1 && styler[pos]=='-' && styler[pos+1]=='-';
}

static void FoldEiffelDocIndent(unsigned int startPos, int length, int,
						   WordList *[], Accessor &styler) {
	int lengthDoc = startPos + length;

	// Backtrack to previous line in case need to fix its fold status
	int lineCurrent = styler.GetLine(startPos);
	if (startPos > 0) {
		if (lineCurrent > 0) {
			lineCurrent--;
			startPos = styler.LineStart(lineCurrent);
		}
	}
	int spaceFlags = 0;
	int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsEiffelComment);
	char chNext = styler[startPos];
	for (int i = startPos; i < lengthDoc; i++) {
		char ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);

		if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc)) {
			int lev = indentCurrent;
			int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsEiffelComment);
			if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
				// Only non whitespace lines can be headers
				if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
					lev |= SC_FOLDLEVELHEADERFLAG;
				} else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
					// Line after is blank so check the next - maybe should continue further?
					int spaceFlags2 = 0;
					int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsEiffelComment);
					if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
						lev |= SC_FOLDLEVELHEADERFLAG;
					}
				}
			}
			indentCurrent = indentNext;
			styler.SetLevel(lineCurrent, lev);
			lineCurrent++;
		}
	}
}

static void FoldEiffelDocKeyWords(unsigned int startPos, int length, int /* initStyle */, WordList *[],
                       Accessor &styler) {
	unsigned int lengthDoc = startPos + length;
	int visibleChars = 0;
	int lineCurrent = styler.GetLine(startPos);
	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
	int levelCurrent = levelPrev;
	char chNext = styler[startPos];
	int stylePrev = 0;
	int styleNext = styler.StyleAt(startPos);
	// lastDeferred should be determined by looking back to last keyword in case
	// the "deferred" is on a line before "class"
	bool lastDeferred = false;
	for (unsigned int i = startPos; i < lengthDoc; i++) {
		char ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);
		int style = styleNext;
		styleNext = styler.StyleAt(i + 1);
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
		if ((stylePrev != SCE_EIFFEL_WORD) && (style == SCE_EIFFEL_WORD)) {
			char s[20];
			unsigned int j = 0;
			while ((j < (sizeof(s) - 1)) && (iswordchar(styler[i + j]))) {
				s[j] = styler[i + j];
				j++;
			}
			s[j] = '\0';

			if (
				(strcmp(s, "check") == 0) ||
				(strcmp(s, "debug") == 0) ||
				(strcmp(s, "deferred") == 0) ||
				(strcmp(s, "do") == 0) ||
				(strcmp(s, "from") == 0) ||
				(strcmp(s, "if") == 0) ||
				(strcmp(s, "inspect") == 0) ||
				(strcmp(s, "once") == 0)
			)
				levelCurrent++;
			if (!lastDeferred && (strcmp(s, "class") == 0))
				levelCurrent++;
			if (strcmp(s, "end") == 0)
				levelCurrent--;
			lastDeferred = strcmp(s, "deferred") == 0;
		}

		if (atEOL) {
			int lev = levelPrev;
			if (visibleChars == 0)
				lev |= SC_FOLDLEVELWHITEFLAG;
			if ((levelCurrent > levelPrev) && (visibleChars > 0))
				lev |= SC_FOLDLEVELHEADERFLAG;
			if (lev != styler.LevelAt(lineCurrent)) {
				styler.SetLevel(lineCurrent, lev);
			}
			lineCurrent++;
			levelPrev = levelCurrent;
			visibleChars = 0;
		}
		if (!isspacechar(ch))
			visibleChars++;
		stylePrev = style;
	}
	// Fill in the real level of the next line, keeping the current flags as they will be filled in later
	int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
	styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}

LexerModule lmEiffel(SCLEX_EIFFEL, ColouriseEiffelDoc, "eiffel", FoldEiffelDocIndent);
LexerModule lmEiffelkw(SCLEX_EIFFELKW, ColouriseEiffelDoc, "eiffelkw", FoldEiffelDocKeyWords);
<commit_msg>Rnamed LexContext to ColouriseContext in case it goes into a separate file. Handling DBCS in Forward method and constructor of ClouriseContext. New safer character categorisation functions take unsigned int arguments to allow DBCS non-ASCII (>= 0x80) characters. ColouriseContext has a chPrev field.<commit_after>// Scintilla source code edit control
/** @file LexEiffel.cxx
 ** Lexer for Eiffel.
 **/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <fcntl.h>

#include "Platform.h"

#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"

inline bool isEiffelOperator(unsigned int ch) {
	// '.' left out as it is used to make up numbers
	return ch == '*' || ch == '/' || ch == '\\' || ch == '-' || ch == '+' ||
	        ch == '(' || ch == ')' || ch == '=' ||
	        ch == '{' || ch == '}' || ch == '~' ||
	        ch == '[' || ch == ']' || ch == ';' ||
	        ch == '<' || ch == '>' || ch == ',' ||
	        ch == '.' || ch == '^' || ch == '%' || ch == ':' ||
		ch == '!' || ch == '@' || ch == '?';
}

static void getRangeLowered(unsigned int start,
		unsigned int end,
		Accessor &styler,
		char *s,
		unsigned int len) {
	unsigned int i = 0;
	while ((i < end - start + 1) && (i < len-1)) {
		s[i] = static_cast<char>(tolower(styler[start + i]));
		i++;
	}
	s[i] = '\0';
}

inline bool IsASpace(unsigned int ch) {
    return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
}

inline bool IsAWordChar(unsigned int  ch) {
	return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
}

inline bool IsAWordStart(unsigned int ch) {
	return (ch < 0x80) && (isalnum(ch) || ch == '_');
}

inline bool IsADigit(unsigned int ch) {
	return (ch >= '0') && (ch <= '9');
}

// All languages handled so far can treat all characters >= 0x80 as one class
// which just continues the current token or starts an identifier if in default.
// DBCS treated specially as the second character can be < 0x80 and hence
// syntactically significant. UTF-8 avoids this as all trail bytes are >= 0x80
class ColouriseContext {
	Accessor &styler;
	int lengthDoc;
	int currentPos;
	ColouriseContext& operator=(const ColouriseContext&) {
		return *this;
	}
public:
	int state;
	unsigned int chPrev;
	unsigned int ch;
	unsigned int chNext;

	ColouriseContext(unsigned int startPos, int length,
                        int initStyle, Accessor &styler_) :
		styler(styler_),
		lengthDoc(startPos + length),
		currentPos(startPos),
		state(initStyle),
		chPrev(0),
		ch(0),
		chNext(0) {
		styler.StartAt(startPos);
		styler.StartSegment(startPos);
		int pos = currentPos;
		ch = static_cast<unsigned char>(styler.SafeGetCharAt(pos));
		if (styler.IsLeadByte(static_cast<char>(ch))) {
			pos++;
			ch = ch << 8;
			ch |= static_cast<unsigned char>(styler.SafeGetCharAt(pos));
		}
		chNext = static_cast<unsigned char>(styler.SafeGetCharAt(pos+1));
		if (styler.IsLeadByte(static_cast<char>(chNext))) {
			chNext = chNext << 8;
			chNext |= static_cast<unsigned char>(styler.SafeGetCharAt(pos+2));
		}
	}
	void Complete() {
		styler.ColourTo(currentPos - 1, state);
	}
	bool More() {
		return currentPos <= lengthDoc;
	}
	void Forward() {
		chPrev = ch;
		currentPos++;
		if (ch >= 0x100)
			currentPos++;
		ch = chNext;
		chNext = static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+1));
		if (styler.IsLeadByte(static_cast<char>(chNext))) {
			chNext = chNext << 8;
			chNext |= static_cast<unsigned char>(styler.SafeGetCharAt(currentPos + 2));
		}
	}
	void ChangeState(int state_) {
		state = state_;
	}
	void SetState(int state_) {
		styler.ColourTo(currentPos - 1, state);
		state = state_;
	}
	void GetCurrentLowered(char *s, int len) {
		getRangeLowered(styler.GetStartSegment(), currentPos - 1, styler, s, len);
	}
};

static void ColouriseEiffelDoc(unsigned int startPos,
                            int length,
                            int initStyle,
                            WordList *keywordlists[],
                            Accessor &styler) {

	WordList &keywords = *keywordlists[0];

	ColouriseContext lc(startPos, length, initStyle, styler);

	for (; lc.More(); lc.Forward()) {

		if (lc.state == SCE_EIFFEL_STRINGEOL) {
			if (lc.ch != '\r' && lc.ch != '\n') {
				lc.SetState(SCE_EIFFEL_DEFAULT);
			}
		} else if (lc.state == SCE_EIFFEL_OPERATOR) {
			lc.SetState(SCE_EIFFEL_DEFAULT);
		} else if (lc.state == SCE_EIFFEL_WORD) {
			if (!IsAWordChar(lc.ch)) {
				char s[100];
				lc.GetCurrentLowered(s, sizeof(s));
				if (!keywords.InList(s)) {
					lc.ChangeState(SCE_EIFFEL_IDENTIFIER);
				}
				lc.SetState(SCE_EIFFEL_DEFAULT);
			}
		} else if (lc.state == SCE_EIFFEL_NUMBER) {
			if (!IsAWordChar(lc.ch)) {
				lc.SetState(SCE_EIFFEL_DEFAULT);
			}
		} else if (lc.state == SCE_EIFFEL_COMMENTLINE) {
			if (lc.ch == '\r' || lc.ch == '\n') {
				lc.SetState(SCE_EIFFEL_DEFAULT);
			}
		} else if (lc.state == SCE_EIFFEL_STRING) {
			if (lc.ch == '%') {
				lc.Forward();
			} else if (lc.ch == '\"') {
				lc.Forward();
				lc.SetState(SCE_EIFFEL_DEFAULT);
			}
		} else if (lc.state == SCE_EIFFEL_CHARACTER) {
			if (lc.ch == '\r' || lc.ch == '\n') {
				lc.SetState(SCE_EIFFEL_STRINGEOL);
			} else if (lc.ch == '%') {
				lc.Forward();
			} else if (lc.ch == '\'') {
				lc.Forward();
				lc.SetState(SCE_EIFFEL_DEFAULT);
			}
		}

		if (lc.state == SCE_EIFFEL_DEFAULT) {
			if (lc.ch == '-' && lc.chNext == '-') {
				lc.SetState(SCE_EIFFEL_COMMENTLINE);
			} else if (lc.ch == '\"') {
				lc.SetState(SCE_EIFFEL_STRING);
			} else if (lc.ch == '\'') {
				lc.SetState(SCE_EIFFEL_CHARACTER);
			} else if (IsADigit(lc.ch) || (lc.ch == '.')) {
				lc.SetState(SCE_EIFFEL_NUMBER);
			} else if (IsAWordStart(lc.ch)) {
				lc.SetState(SCE_EIFFEL_WORD);
			} else if (isEiffelOperator(lc.ch)) {
				lc.SetState(SCE_EIFFEL_OPERATOR);
			}
		}
	}
	lc.Complete();
}

static bool IsEiffelComment(Accessor &styler, int pos, int len) {
	return len>1 && styler[pos]=='-' && styler[pos+1]=='-';
}

static void FoldEiffelDocIndent(unsigned int startPos, int length, int,
						   WordList *[], Accessor &styler) {
	int lengthDoc = startPos + length;

	// Backtrack to previous line in case need to fix its fold status
	int lineCurrent = styler.GetLine(startPos);
	if (startPos > 0) {
		if (lineCurrent > 0) {
			lineCurrent--;
			startPos = styler.LineStart(lineCurrent);
		}
	}
	int spaceFlags = 0;
	int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsEiffelComment);
	char chNext = styler[startPos];
	for (int i = startPos; i < lengthDoc; i++) {
		char ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);

		if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc)) {
			int lev = indentCurrent;
			int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsEiffelComment);
			if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
				// Only non whitespace lines can be headers
				if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
					lev |= SC_FOLDLEVELHEADERFLAG;
				} else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
					// Line after is blank so check the next - maybe should continue further?
					int spaceFlags2 = 0;
					int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsEiffelComment);
					if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
						lev |= SC_FOLDLEVELHEADERFLAG;
					}
				}
			}
			indentCurrent = indentNext;
			styler.SetLevel(lineCurrent, lev);
			lineCurrent++;
		}
	}
}

static void FoldEiffelDocKeyWords(unsigned int startPos, int length, int /* initStyle */, WordList *[],
                       Accessor &styler) {
	unsigned int lengthDoc = startPos + length;
	int visibleChars = 0;
	int lineCurrent = styler.GetLine(startPos);
	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
	int levelCurrent = levelPrev;
	char chNext = styler[startPos];
	int stylePrev = 0;
	int styleNext = styler.StyleAt(startPos);
	// lastDeferred should be determined by looking back to last keyword in case
	// the "deferred" is on a line before "class"
	bool lastDeferred = false;
	for (unsigned int i = startPos; i < lengthDoc; i++) {
		char ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);
		int style = styleNext;
		styleNext = styler.StyleAt(i + 1);
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
		if ((stylePrev != SCE_EIFFEL_WORD) && (style == SCE_EIFFEL_WORD)) {
			char s[20];
			unsigned int j = 0;
			while ((j < (sizeof(s) - 1)) && (iswordchar(styler[i + j]))) {
				s[j] = styler[i + j];
				j++;
			}
			s[j] = '\0';

			if (
				(strcmp(s, "check") == 0) ||
				(strcmp(s, "debug") == 0) ||
				(strcmp(s, "deferred") == 0) ||
				(strcmp(s, "do") == 0) ||
				(strcmp(s, "from") == 0) ||
				(strcmp(s, "if") == 0) ||
				(strcmp(s, "inspect") == 0) ||
				(strcmp(s, "once") == 0)
			)
				levelCurrent++;
			if (!lastDeferred && (strcmp(s, "class") == 0))
				levelCurrent++;
			if (strcmp(s, "end") == 0)
				levelCurrent--;
			lastDeferred = strcmp(s, "deferred") == 0;
		}

		if (atEOL) {
			int lev = levelPrev;
			if (visibleChars == 0)
				lev |= SC_FOLDLEVELWHITEFLAG;
			if ((levelCurrent > levelPrev) && (visibleChars > 0))
				lev |= SC_FOLDLEVELHEADERFLAG;
			if (lev != styler.LevelAt(lineCurrent)) {
				styler.SetLevel(lineCurrent, lev);
			}
			lineCurrent++;
			levelPrev = levelCurrent;
			visibleChars = 0;
		}
		if (!isspacechar(ch))
			visibleChars++;
		stylePrev = style;
	}
	// Fill in the real level of the next line, keeping the current flags as they will be filled in later
	int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
	styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}

LexerModule lmEiffel(SCLEX_EIFFEL, ColouriseEiffelDoc, "eiffel", FoldEiffelDocIndent);
LexerModule lmEiffelkw(SCLEX_EIFFELKW, ColouriseEiffelDoc, "eiffelkw", FoldEiffelDocKeyWords);
<|endoftext|>