exceptions4c 4.0
Exceptions for C
Loading...
Searching...
No Matches
exceptions4c.c File Reference

Implementation of the exception handling library for C. More...

#include <stdio.h>
#include <errno.h>
#include <stdarg.h>
#include <stdnoreturn.h>
#include <exceptions4c.h>

Functions

void e4c_set_context_supplier (struct e4c_context *(*supplier)(void))
 Sets the exception context supplier.
 
struct e4c_contexte4c_get_context (void)
 Supplies the current exception context.
 
const struct e4c_exceptione4c_get_exception (void)
 Retrieves the last exception that was thrown.
 
bool e4c_is_uncaught (void)
 Determines whether the thrown exception was not caught.
 

Detailed Description

Implementation of the exception handling library for C.

Version
4.0.0
Author
Guillermo Calvo
See also
For more information, visit the project on GitHub.

Function Documentation

◆ e4c_set_context_supplier()

void e4c_set_context_supplier ( struct e4c_context *(* supplier )(void))

Sets the exception context supplier.

The library relies on this context to handle the current status of exceptions. If no supplier is provided, a default one will be used.

Remarks
Since the default exception context does not support concurrency, this mechanism can be useful to provide a concurrent version. For example, a context supplier could return different instances, depending on which thread is active. In that case, the supplier MUST be responsible for the creation and deletion of those instances.

Example:

static struct e4c_context my_custom_context = {
.initialize_exception = my_initializer,
.finalize_exception = my_finalizer
};
static struct e4c_context * my_context_supplier(void) {
return &my_custom_context;
}
int main(void) {
e4c_set_context_supplier(my_context_supplier);
TRY {
THROW(PET_ERROR, "Bad dog");
const struct my_custom_data * data = e4c_get_exception()->data;
printf("MSG: %s\n", data->msg);
}
return EXIT_SUCCESS;
}
Parameters
supplierThe function that supplies the current exception context.
See also
e4c_context

◆ e4c_get_context()

struct e4c_context * e4c_get_context ( void )

Supplies the current exception context.

Remarks
The objected returned by this function MAY be used to configure the program's current exception context. For example, you can set a custom handler that will be executed when the program abruptly terminates due to an uncaught exception.

Example:

static void my_uncaught_handler(const struct e4c_exception * exception) {
fprintf(stderr, "UNCAUGHT: %s\n", exception->message);
}
int main(int argc, char * argv[]) {
e4c_get_context()->uncaught_handler = my_uncaught_handler;
THROW(MY_ERROR, "Oops");
}
Returns
The current exception context.
See also
e4c_context
e4c_set_context_supplier

◆ e4c_get_exception()

const struct e4c_exception * e4c_get_exception ( void )

Retrieves the last exception that was thrown.

Remarks
This function SHOULD be used in the body of a CATCH or CATCH_ALL block to inspect the exception being handled. It MAY also be used in the body of a FINALLY block to determine if an exception was thrown in the corresponding TRY block, or during the execution of a CATCH or CATCH_ALL block.

Example:

/* Returns the status of a pet by id */
pet_status get_pet_status(int id) {
pet_status status = ERROR;
TRY {
status = pet_find(id)->status;
if (e4c_get_exception()->type == &NOT_ENOUGH_MEMORY) {
abort();
}
status = UNKNOWN;
}
return status;
}
Returns
The last exception that was thrown.
See also
e4c_exception
THROW
CATCH
FINALLY
e4c_is_uncaught

◆ e4c_is_uncaught()

bool e4c_is_uncaught ( void )

Determines whether the thrown exception was not caught.

An exception is considered "uncaught" if no matching CATCH or CATCH_ALL block has been executed for it. In other words, this function returns true if the exception has bypassed all specific exception-handling logic and is propagating further. And it returns false if no exception was thrown in the TRY block, or if an exception was successfully caught.

Remarks
This function SHOULD be used exclusively in the body of a FINALLY block to check whether an exception thrown during the TRY block has propagated past all CATCH and CATCH_ALL blocks without being handled.

Example:

int main(int argc, char * argv[]) {
TRY {
process_data(argc, argv);
} FINALLY {
if (e4c_is_uncaught()) {
fprintf(stderr, "Fatal error while processing data.\n");
} else {
fprintf(stdout, "Data processed successfully.\n");
}
}
return EXIT_SUCCESS;
}
Returns
true if the current exception (if any) has not yet been handled by any CATCH or CATCH_ALL block; false otherwise.
See also
FINALLY
e4c_get_exception