/* try.c -- try / catch / throw exception handling for C99
 * For copyright, version, and conditions of distribution and use, see try.h
 */

/* See try.h for documentation.  This source file provides the global pointer
   and the functions needed by throw().  The pointer is thread-unique if
   pthread.h is included in try.h. */

#include "try.h"
#include <stdio.h>
#include <string.h>
#include <stdarg.h>

/* Set up the try stack with a global pointer to the next try block.  The
   global is thread-unique if pthread.h is included in try.h. */
#ifdef PTHREAD_ONCE_INIT
    pthread_key_t try_key_;
    static pthread_once_t try_once_ = PTHREAD_ONCE_INIT;
    static void try_create_(void)
    {
        int ret = pthread_key_create(&try_key_, NULL);
        assert(ret == 0 && "try: pthread_key_create() failed");
    }
    void try_setup_(void)
    {
        int ret = pthread_once(&try_once_, try_create_);
        assert(ret == 0 && "try: pthread_once() failed");
    }
#else /* !PTHREAD_ONCE_INIT */
    try_t_ *try_stack_ = NULL;
#endif /* PTHREAD_ONCE_INIT */

/* Throw an exception.  This must always have at least two arguments, where the
   second argument can be a NULL.  The throw() macro is permitted to have one
   argument, since it appends a NULL argument in the call to this function. */
void try_throw_(int code, char *fmt, ...)
{
    /* save the thrown information in the try stack before jumping */
    try_setup_();
    assert(try_stack_ != NULL && "try: naked throw");
    try_stack_->ball.ret = 1;
    try_stack_->ball.code = code;
    try_stack_->ball.free = 0;
    try_stack_->ball.why = fmt;

    /* consider the second argument to be a string, and if it has formatting
       commands, process them with the subsequent arguments of throw, saving
       the result in allocated memory -- this if statement and clause must be
       updated for a different interpretation of the throw() arguments and
       different contents of the ball_t structure */
    if (fmt != NULL && strchr(fmt, '%') != NULL) {
        char *why, nul[1];
        size_t len;
        va_list ap1, ap2;

        va_start(ap1, fmt);
        va_copy(ap2, ap1);
        len = vsnprintf(nul, 1, fmt, ap1);
        va_end(ap1);
        why = malloc(len + 1);
        if (why == NULL)
            try_stack_->ball.why = "try: out of memory";
        else {
            vsnprintf(why, len + 1, fmt, ap2);
            va_end(ap2);
            try_stack_->ball.free = 1;
            try_stack_->ball.why = why;
        }
    }

    /* jump to the end of the nearest enclosing try block */
    longjmp(try_stack_->env, 1);
}
