6 n__exceptions_8h
gullradriel edited this page 2026-10-09 00:55:18 +02:00

include/nilorea/n_exceptions.h

Exception management for C. More...

Structures

Name
struct ExceptionContextList
Exception stack structure.

Detailed Description

Exception management for C.

Author: Castagnier Mickael

Version: 1.0

Date: 20/11/09

Source code

/*
 * Nilorea Library
 * Copyright (C) 2005-2026 Castagnier Mickael
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License.
 *
 * SPDX-License-Identifier: Apache-2.0
 */


#ifndef ____EXCEPTION___MANAGEMENT__FOR_C
#define ____EXCEPTION___MANAGEMENT__FOR_C

#ifdef __cplusplus
extern "C" {
#endif


#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>

#define NO_EXCEPTION 0
#define ARRAY_EXCEPTION 2
#define DIVZERO_EXCEPTION 4
#define OVERFLOW_EXCEPTION 8
#define PARSING_EXCEPTION 16

#define GENERAL_EXCEPTION (ARRAY_EXCEPTION | DIVZERO_EXCEPTION | OVERFLOW_EXCEPTION | PARSING_EXCEPTION)

typedef struct ExceptionContextList {
    jmp_buf context;
    struct ExceptionContextList* head;
} ExceptionContextList;

extern __thread ExceptionContextList* __Exceptions;

void push_exception(void);
void pop_exception(int ex);

#define Try                                     \
    {                                           \
        volatile int __exc_;                    \
        push_exception();                       \
        __exc_ = setjmp(__Exceptions->context); \
        if (__exc_ == NO_EXCEPTION) {
#define Catch(X)        \
    }                   \
    if (__exc_ & (X)) { \
        __exc_ = 0;

#define CatchAll()     \
    }                  \
    if (__exc_ != 0) { \
        __exc_ = 0;

#define EndTry             \
    }                      \
    pop_exception(__exc_); \
    }

#define Throw(X)                                                         \
    do {                                                                 \
        int __exc_val_ = (X);                                            \
        n_log(LOG_ERR, "Exception thrown: %d", __exc_val_);              \
        if (__Exceptions) {                                              \
            longjmp(__Exceptions->context, __exc_val_ ? __exc_val_ : 1); \
        } else {                                                         \
            n_log(LOG_ERR, "Throw called outside Try block!");           \
            abort();                                                     \
        }                                                                \
    } while (0)


#ifdef __cplusplus
}
#endif

#endif /* #ifndef ____EXCEPTION___MANAGEMENT__FOR_C  */