Try a catch em C
A linguagem C não possui suporte nativo a estruturas de tratamento de excessões, entretanto esse problema pode ser contornado em algumas situações.
Na linguagem C existem duas funções que podem ser utilizadas para esse fim setjmp longjmp.
A função setjmp salva o estado de uma variavel do tipo jump_buf, que é recuperado pela função longjmp. Desta maneira é possível criar uma variavel enviroment para salvar o estado de um bloco de código.
Para facilitar a utilização dessas funções é possível criar macros que manipulam essas funções.
Separei a implementação em arquivos diferentes:
throws.h
...
typedef struct throwable {
int line;
char message[MAX_ERROR_MESSAGE_LENGTH];
char filename[MAX_ERROR_FILENAME_LENGTH];
char functionName[MAX_ERROR_FUNCTION_NAME_LENGTH];
} Throwable;
typedef struct throwableType {
int code;
char message[MAX_ERROR_MESSAGE_LENGTH];
} ThrowableType;
extern Throwable * throwable;
extern ThrowableType throwableTypes[];
...
throws.c
#include "throws.h"
Throwable * throwable;
ThrowableType throwableTypes[] = {
{EMPTY_ARRAY_ERROR, "ERROR: The array is empty"},
{DIVISION_BY_ZERO_ERROR, "ERROR: Division by zero"},
{EMPTY_POSITION_ERROR, "ERROR: The position is empty"},
{TYPE_ERROR, "ERROR: Type error"},
{RANGE_ERROR, "ERROR: Range Error"},
{REFERENCE_ERROR, "ERROR: Reference error"},
{URI_ERROR, "ERROR: URI error"},
{INTERNAL_ERROR, "ERROR: Internal error"},
{NOT_DEFINED_ERROR, "ERROR: Not defined"},
{FILE_INSERTION_ERROR, "ERROR: The file insertion failed!"},
{OPENING_FILE_ERROR, "ERROR: Error opening file!"},
{FILE_READING_ERROR, "ERROR: Error reading file!"},
{FILE_REALPATH_ERROR, "ERROR: Error to get file's absolute path"}
};
void throws(jmp_buf savebuf, int value, int line, const char functionName[], const char filename[])
{
throwable = (Throwable *) malloc(sizeof(Throwable));
strcpy(throwable->message, throwableTypes[value].message);
strcpy(throwable->functionName, functionName);
strcpy(throwable->filename, filename);
throwable->line = line;
longjmp(savebuf, value);
}
String getCurrentThrowableMessage()
{
return throwable->message;
}
...
throwable.h
#ifndef THROWABLE_H_INCLUDED
#define THROWABLE_H_INCLUDED
#include <setjmp.h>
#include "throws.h"
extern jmp_buf savebuf;
extern int exceptionVal;
#define TRY if ((exceptionVal = setjmp(savebuf)) == 0)
#define CATCH(NUM) else if (exceptionVal == NUM)
#define CATCHALL else
#define FINALLY if (1)
#define THROW(NUM) throws(savebuf, NUM, __LINE__, __FUNCTION__, __FILE__)
#endif // THROWABLE_H_INCLUDED