[C++] Classe pour la gestion d'exception

Statut
N'est pas ouverte pour d'autres réponses.

neku

Codeur roumain
Voila, je partage cette petit classe que j'ai commencé qui permet une petit gestion des exception avec try/throw/catch en c++

Code:
#include <iostream>
#include <fstream>
#include <stdarg.h>

using namespace std;

#ifdef _WIN32_
	__declspec (naked) void* __builtin_return_address (int iLevel)
	{
		__asm
		{
			push ebx;

			mov eax, ebp;
			mov ebx, DWORD PTR [esp + 8]; // iLevel

	__Next:
			test ebx, ebx;
			je  __break;
			dec ebx;
			mov eax, DWORD PTR [eax];
			jmp __Next;
	__break:

			mov eax, DWORD PTR [eax + 4];
			pop ebx;
			ret;
		}
	}
#endif

#define REDIRECT_COUT_TO_LOG() \
	ofstream Log_File("./debug.log", ios::app); \
	streambuf* Buffer_log = Log_File.rdbuf(); \
	streambuf* Buffer_cout = cout.rdbuf(); \
	cout.rdbuf(Buffer_log);

#define REDIRECT_COUT_TO_COUT() \
	cout.rdbuf(Buffer_cout); \
	Log_File.close();

enum ExceptionType {
	RETURN_TRUE,
};

class API_ExceptionHandle {
public:
	API_ExceptionHandle (const char* Note, const char* File, const char* Function, int Line, void* Return_Address, void* Call_Return_Address, enum ExceptionType Type);
	const char* GetMessage ();
	int GetLine ();
	const char* GetFile ();
	const char* GetFunction ();
	void GetArgs (const char* Format, ...);
	void* GetReturnAddress ();
	void* GetCallReturnAddress ();
private:
	string Message;
	int Line;
	string File;
	string Function;
	int Type;
	void* Return_Address;
	void* Call_Return_Address;
};

#define HandleException(Note, Type) API_ExceptionHandle(Note, __FILE__, __PRETTY_FUNCTION__, __LINE__, __builtin_return_address(0), __builtin_return_address(1), Type);

API_ExceptionHandle::API_ExceptionHandle (const char* Note, const char* File, const char* Function, int Line, void* Return_Address, void* Call_Return_Address, enum ExceptionType Type) {
	this->Message = Note;
	this->Line = Line;
	this->Function = Function;
	this->File = File;
	this->Type = Type;
	this->Return_Address = Return_Address;
	this->Call_Return_Address = Call_Return_Address;
}

const char* API_ExceptionHandle::GetMessage() {
	return this->Message.c_str();
}

const char* API_ExceptionHandle::GetFile() {
	return this->File.c_str();
}

const char* API_ExceptionHandle::GetFunction() {
	return this->Function.c_str();
}

int API_ExceptionHandle::GetLine() {
	return this->Line;
}

void* API_ExceptionHandle::GetReturnAddress() {
	return this->Return_Address;
}

void* API_ExceptionHandle::GetCallReturnAddress() {
	return this->Call_Return_Address;
}

void API_ExceptionHandle::GetArgs (const char* Format, ...) {
	char* tmp = (char*)Format;
	bool Begin_Type = false;
	bool End_Type = false;
	bool Table = false;
	int Counter = 0;
	int Table_Counter = 0;
	
	va_list va_alist;
	va_start(va_alist, Format);
	
	cout << "<Args>" << endl;
	
	while (*tmp) {
		if (*tmp == '%') {
			Begin_Type = true;
		}
		
		if ((*(tmp + 1) == '[') && (*(tmp + 2) == ']') && (Begin_Type == true)) {
			Table = true;
			if ((*(tmp + 3) == ',') || (*(tmp + 3) == '\0')) {
				End_Type = true;
			}
		}
		else {
			if ((*(tmp + 1) == ',') || (*(tmp + 1) == '\0')) {
				End_Type = true;
			}
		}
		
		if ((Begin_Type == true) && (End_Type == true)) {
			Counter++;
			cout << "	|-- Arg [" << Counter << "]: ";
			if (*tmp == 'i' || *tmp == 'd')
				cout << dec << va_arg(va_alist, int) << endl;
			else if (*tmp == 'f') {
				cout << dec << va_arg(va_alist, double) << endl;
			}
			else if (*tmp == 'x') {
				cout << "0x" << hex << va_arg(va_alist, int) << endl;
			}
			else if (*tmp == 's') {
				if (Table) {
					char** tmpTab = va_arg(va_alist, char**);
					char* tmpString = *(tmpTab + 0);
					cout << endl;
					while (tmpString) {
						cout << "	|	|----- [" << dec << Table_Counter << "]: " << tmpString << endl;
						tmpString = *(++tmpTab);
						Table_Counter++;
					}
					cout << "	|" << endl;
					Table_Counter = 0;
				}
				else {
					char* tmpString = va_arg(va_alist, char*);
					cout << tmpString << endl;
				}
			}
			
			if (Table)
				tmp += 2;
			
			Begin_Type = false;
			End_Type = false;
			Table = false;
		}
		*tmp++;
	}
	
	va_end(va_alist);
	
	cout << "</Args>" << endl;
}

int main (int argc, char const* argv[])
{
	//REDIRECT_COUT_TO_LOG()
	try {
		if (true) throw HandleException("Oh non ca a encore ... ! :'(", RETURN_TRUE)
			cout << "coucou" << endl;
	}
	catch (API_ExceptionHandle &eHandle) {
		cout << "<File>" << endl << "	" << eHandle.GetFile() << endl << "</File>" << endl;
		cout << "<Function>" << endl << "	" << eHandle.GetFunction() << endl << "</Function>" << endl;
		cout << "<Line>" << endl << "	" << eHandle.GetLine() << endl << "</Line>" << endl;
		cout << "<Return Address>" << endl << "	" << eHandle.GetReturnAddress() << endl << "</Return Address>" << endl;
		cout << "<Call Return Address>" << endl << "	" << eHandle.GetReturnAddress() << endl << "</Call Return Address>" << endl;
		cout << "<Note>" << endl << "	" << eHandle.GetMessage() << endl << "</Note>" << endl;
		eHandle.GetArgs("%i,%s[]", argc, argv);
	}
		
	//REDIRECT_COUT_TO_COUT()
	return 0;
}
le resultat lors de l'exécution :

Code:
ordinateur-de-leandre-gohy:~/Desktop/DVRNS leandregohy$ ./test 
<File>
	test.cpp
</File>
<Function>
	int main(int, const char**)
</Function>
<Line>
	181
</Line>
<Return Address>
	0x1d6e
</Return Address>
<Call Return Address>
	0x1d6e
</Call Return Address>
<Note>
	Oh non ca a encore ... ! :'(
</Note>
<Args>
	|-- Arg [1]: 1
	|-- Arg [2]: 
	|	|----- [0]: ./test
	|
</Args>
ordinateur-de-leandre-gohy:~/Desktop/DVRNS leandregohy$
Certe elle peut être améliorée & optimisée mais c'est une classe faite en vitesse car j'en avais besoin.
 
Statut
N'est pas ouverte pour d'autres réponses.
Haut