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

Discussion dans 'Web, design' créé par neku, 20 Avril 2007.

Statut de la discussion:
Fermée.
  1. Offline
    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.
    neku, 20 Avril 2007
    #1
Statut de la discussion:
Fermée.