summaryrefslogtreecommitdiff
path: root/pjlib/include/pj/except.h
diff options
context:
space:
mode:
Diffstat (limited to 'pjlib/include/pj/except.h')
-rw-r--r--pjlib/include/pj/except.h568
1 files changed, 284 insertions, 284 deletions
diff --git a/pjlib/include/pj/except.h b/pjlib/include/pj/except.h
index a0143b9c..301242a4 100644
--- a/pjlib/include/pj/except.h
+++ b/pjlib/include/pj/except.h
@@ -1,284 +1,284 @@
-/* $Id$ */
-/*
- * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef __PJ_EXCEPTION_H__
-#define __PJ_EXCEPTION_H__
-
-/**
- * @file except.h
- * @brief Exception Handling in C.
- */
-
-#include <pj/types.h>
-#include <pj/compat/setjmp.h>
-
-
-PJ_BEGIN_DECL
-
-
-/**
- * @defgroup PJ_EXCEPT Exception Handling
- * @ingroup PJ_MISC
- * @{
- *
- * \section pj_except_sample_sec Quick Example
- *
- * For the impatient, take a look at some examples:
- * - @ref page_pjlib_samples_except_c
- * - @ref page_pjlib_exception_test
- *
- * \section pj_except_except Exception Handling
- *
- * This module provides exception handling syntactically similar to C++ in
- * C language. The underlying mechanism use setjmp() and longjmp(), and since
- * these constructs are ANSI standard, the mechanism here should be available
- * on most platforms/compilers which are ANSI compliant.
- *
- * If ANSI libc is not available, then setjmp()/longjmp() implementation will
- * be provided. See <pj/compat/setjmp.h> for compatibility.
- *
- * The exception handling mechanism is completely thread safe, so the exception
- * thrown by one thread will not interfere with other thread.
- *
- * CAVEATS:
- * - unlike C++ exception, the scheme here won't call destructors of local
- * objects if exception is thrown. Care must be taken when a function
- * hold some resorce such as pool or mutex etc.
- * - You CAN NOT make nested exception in one single function without using
- * a nested PJ_USE_EXCEPTION.
- * - Exceptions will always be caught by the first handle (unlike C++ where
- * exception is only caught if the type matches.
- *
- * The exception handling constructs are similar to C++. The blocks will be
- * constructed similar to the following sample:
- *
- * \verbatim
- #define NO_MEMORY 1
- #define SYNTAX_ERROR 2
-
- int main()
- {
- PJ_USE_EXCEPTION; // declare local exception stack.
-
- PJ_TRY {
- ...// do something..
- }
- PJ_CATCH(NO_MEMORY) {
- ... // handle exception 1
- }
- PJ_CATCH(SYNTAX_ERROR) {
- ... // handle exception 2
- }
- PJ_DEFAULT {
- ... // handle other exceptions.
- }
- PJ_END;
- }
- \endverbatim
- *
- * The above sample uses hard coded exception ID. It is @b strongly
- * recommended that applications request a unique exception ID instead
- * of hard coded value like above.
- *
- * \section pj_except_reg Exception ID Allocation
- *
- * To ensure that exception ID (number) are used consistently and to
- * prevent ID collisions in an application, it is strongly suggested that
- * applications allocate an exception ID for each possible exception
- * type. As a bonus of this process, the application can identify
- * the name of the exception when the particular exception is thrown.
- *
- * Exception ID management are performed with the following APIs:
- * - #pj_exception_id_alloc().
- * - #pj_exception_id_free().
- * - #pj_exception_id_name().
- *
- *
- * PJLIB itself automatically allocates one exception id, i.e.
- * #PJ_NO_MEMORY_EXCEPTION which is declared in <pj/pool.h>. This exception
- * ID is raised by default pool policy when it fails to allocate memory.
- *
- * \section PJ_EX_KEYWORDS Keywords
- *
- * \subsection PJ_THROW PJ_THROW(expression)
- * Throw an exception. The expression thrown is an integer as the result of
- * the \a expression. This keyword can be specified anywhere within the
- * program.
- *
- * \subsection PJ_USE_EXCEPTION PJ_USE_EXCEPTION
- * Specify this in the variable definition section of the function block
- * (or any blocks) to specify that the block has \a PJ_TRY/PJ_CATCH exception
- * block.
- * Actually, this is just a macro to declare local variable which is used to
- * push the exception state to the exception stack.
- *
- * \subsection PJ_TRY PJ_TRY
- * The \a PJ_TRY keyword is typically followed by a block. If an exception is
- * thrown in this block, then the execution will resume to the \a PJ_CATCH
- * handler.
- *
- * \subsection PJ_CATCH PJ_CATCH(expression)
- * The \a PJ_CATCH is normally followed by a block. This block will be executed
- * if the exception being thrown is equal to the expression specified in the
- * \a PJ_CATCH.
- *
- * \subsection PJ_DEFAULT PJ_DEFAULT
- * The \a PJ_DEFAULT keyword is normally followed by a block. This block will
- * be executed if the exception being thrown doesn't match any of the \a
- * PJ_CATCH specification. The \a PJ_DEFAULT block \b MUST be placed as the
- * last block of the handlers.
- *
- * \subsection PJ_END PJ_END
- * Specify this keyword to mark the end of \a PJ_TRY / \a PJ_CATCH blocks.
- *
- * \subsection PJ_GET_EXCEPTION PJ_GET_EXCEPTION(void)
- * Get the last exception thrown. This macro is normally called inside the
- * \a PJ_CATCH or \a PJ_DEFAULT block, altough it can be used anywhere where
- * the \a PJ_USE_EXCEPTION definition is in scope.
- *
- *
- * \section pj_except_examples_sec Examples
- *
- * For some examples on how to use the exception construct, please see:
- * - @ref page_pjlib_samples_except_c
- * - @ref page_pjlib_exception_test
- */
-
-/**
- * Allocate a unique exception id.
- * Applications don't have to allocate a unique exception ID before using
- * the exception construct. However, by doing so it ensures that there is
- * no collisions of exception ID.
- *
- * As a bonus, when exception number is acquired through this function,
- * the library can assign name to the exception (only if
- * PJ_HAS_EXCEPTION_NAMES is enabled (default is yes)) and find out the
- * exception name when it catches an exception.
- *
- * @param name Name to be associated with the exception ID.
- * @param id Pointer to receive the ID.
- *
- * @return PJ_SUCCESS on success or PJ_ETOOMANY if the library
- * is running out out ids.
- */
-PJ_DECL(pj_status_t) pj_exception_id_alloc(const char *name,
- pj_exception_id_t *id);
-
-/**
- * Free an exception id.
- *
- * @param id The exception ID.
- *
- * @return PJ_SUCCESS or the appropriate error code.
- */
-PJ_DECL(pj_status_t) pj_exception_id_free(pj_exception_id_t id);
-
-/**
- * Retrieve name associated with the exception id.
- *
- * @param id The exception ID.
- *
- * @return The name associated with the specified ID.
- */
-PJ_DECL(const char*) pj_exception_id_name(pj_exception_id_t id);
-
-
-/** @} */
-
-/**
- * This structure (which should be invisible to user) manages the TRY handler
- * stack.
- */
-struct pj_exception_state_t
-{
- struct pj_exception_state_t *prev; /**< Previous state in the list. */
- pj_jmp_buf state; /**< jmp_buf. */
-};
-
-/**
- * Throw exception.
- * @param id Exception Id.
- */
-PJ_DECL_NO_RETURN(void)
-pj_throw_exception_(pj_exception_id_t id) PJ_ATTR_NORETURN;
-
-/**
- * Push exception handler.
- */
-PJ_DECL(void) pj_push_exception_handler_(struct pj_exception_state_t *rec);
-
-/**
- * Pop exception handler.
- */
-PJ_DECL(void) pj_pop_exception_handler_(void);
-
-/**
- * Declare that the function will use exception.
- * @hideinitializer
- */
-#define PJ_USE_EXCEPTION struct pj_exception_state_t pj_x_except__; int pj_x_code__
-
-/**
- * Start exception specification block.
- * @hideinitializer
- */
-#define PJ_TRY if (1) { \
- pj_push_exception_handler_(&pj_x_except__); \
- pj_x_code__ = pj_setjmp(pj_x_except__.state); \
- if (pj_x_code__ == 0)
-/**
- * Catch the specified exception Id.
- * @param id The exception number to catch.
- * @hideinitializer
- */
-#define PJ_CATCH(id) else if (pj_x_code__ == (id))
-
-/**
- * Catch any exception number.
- * @hideinitializer
- */
-#define PJ_DEFAULT else
-
-/**
- * End of exception specification block.
- * @hideinitializer
- */
-#define PJ_END pj_pop_exception_handler_(); \
- } else {}
-
-/**
- * Throw exception.
- * @param exception_id The exception number.
- * @hideinitializer
- */
-#define PJ_THROW(exception_id) pj_throw_exception_(exception_id)
-
-/**
- * Get current exception.
- * @return Current exception code.
- * @hideinitializer
- */
-#define PJ_GET_EXCEPTION() (pj_x_code__)
-
-PJ_END_DECL
-
-
-
-#endif /* __PJ_EXCEPTION_H__ */
-
-
+/* $Id$ */
+/*
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJ_EXCEPTION_H__
+#define __PJ_EXCEPTION_H__
+
+/**
+ * @file except.h
+ * @brief Exception Handling in C.
+ */
+
+#include <pj/types.h>
+#include <pj/compat/setjmp.h>
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJ_EXCEPT Exception Handling
+ * @ingroup PJ_MISC
+ * @{
+ *
+ * \section pj_except_sample_sec Quick Example
+ *
+ * For the impatient, take a look at some examples:
+ * - @ref page_pjlib_samples_except_c
+ * - @ref page_pjlib_exception_test
+ *
+ * \section pj_except_except Exception Handling
+ *
+ * This module provides exception handling syntactically similar to C++ in
+ * C language. The underlying mechanism use setjmp() and longjmp(), and since
+ * these constructs are ANSI standard, the mechanism here should be available
+ * on most platforms/compilers which are ANSI compliant.
+ *
+ * If ANSI libc is not available, then setjmp()/longjmp() implementation will
+ * be provided. See <pj/compat/setjmp.h> for compatibility.
+ *
+ * The exception handling mechanism is completely thread safe, so the exception
+ * thrown by one thread will not interfere with other thread.
+ *
+ * CAVEATS:
+ * - unlike C++ exception, the scheme here won't call destructors of local
+ * objects if exception is thrown. Care must be taken when a function
+ * hold some resorce such as pool or mutex etc.
+ * - You CAN NOT make nested exception in one single function without using
+ * a nested PJ_USE_EXCEPTION.
+ * - Exceptions will always be caught by the first handle (unlike C++ where
+ * exception is only caught if the type matches.
+ *
+ * The exception handling constructs are similar to C++. The blocks will be
+ * constructed similar to the following sample:
+ *
+ * \verbatim
+ #define NO_MEMORY 1
+ #define SYNTAX_ERROR 2
+
+ int main()
+ {
+ PJ_USE_EXCEPTION; // declare local exception stack.
+
+ PJ_TRY {
+ ...// do something..
+ }
+ PJ_CATCH(NO_MEMORY) {
+ ... // handle exception 1
+ }
+ PJ_CATCH(SYNTAX_ERROR) {
+ ... // handle exception 2
+ }
+ PJ_DEFAULT {
+ ... // handle other exceptions.
+ }
+ PJ_END;
+ }
+ \endverbatim
+ *
+ * The above sample uses hard coded exception ID. It is @b strongly
+ * recommended that applications request a unique exception ID instead
+ * of hard coded value like above.
+ *
+ * \section pj_except_reg Exception ID Allocation
+ *
+ * To ensure that exception ID (number) are used consistently and to
+ * prevent ID collisions in an application, it is strongly suggested that
+ * applications allocate an exception ID for each possible exception
+ * type. As a bonus of this process, the application can identify
+ * the name of the exception when the particular exception is thrown.
+ *
+ * Exception ID management are performed with the following APIs:
+ * - #pj_exception_id_alloc().
+ * - #pj_exception_id_free().
+ * - #pj_exception_id_name().
+ *
+ *
+ * PJLIB itself automatically allocates one exception id, i.e.
+ * #PJ_NO_MEMORY_EXCEPTION which is declared in <pj/pool.h>. This exception
+ * ID is raised by default pool policy when it fails to allocate memory.
+ *
+ * \section PJ_EX_KEYWORDS Keywords
+ *
+ * \subsection PJ_THROW PJ_THROW(expression)
+ * Throw an exception. The expression thrown is an integer as the result of
+ * the \a expression. This keyword can be specified anywhere within the
+ * program.
+ *
+ * \subsection PJ_USE_EXCEPTION PJ_USE_EXCEPTION
+ * Specify this in the variable definition section of the function block
+ * (or any blocks) to specify that the block has \a PJ_TRY/PJ_CATCH exception
+ * block.
+ * Actually, this is just a macro to declare local variable which is used to
+ * push the exception state to the exception stack.
+ *
+ * \subsection PJ_TRY PJ_TRY
+ * The \a PJ_TRY keyword is typically followed by a block. If an exception is
+ * thrown in this block, then the execution will resume to the \a PJ_CATCH
+ * handler.
+ *
+ * \subsection PJ_CATCH PJ_CATCH(expression)
+ * The \a PJ_CATCH is normally followed by a block. This block will be executed
+ * if the exception being thrown is equal to the expression specified in the
+ * \a PJ_CATCH.
+ *
+ * \subsection PJ_DEFAULT PJ_DEFAULT
+ * The \a PJ_DEFAULT keyword is normally followed by a block. This block will
+ * be executed if the exception being thrown doesn't match any of the \a
+ * PJ_CATCH specification. The \a PJ_DEFAULT block \b MUST be placed as the
+ * last block of the handlers.
+ *
+ * \subsection PJ_END PJ_END
+ * Specify this keyword to mark the end of \a PJ_TRY / \a PJ_CATCH blocks.
+ *
+ * \subsection PJ_GET_EXCEPTION PJ_GET_EXCEPTION(void)
+ * Get the last exception thrown. This macro is normally called inside the
+ * \a PJ_CATCH or \a PJ_DEFAULT block, altough it can be used anywhere where
+ * the \a PJ_USE_EXCEPTION definition is in scope.
+ *
+ *
+ * \section pj_except_examples_sec Examples
+ *
+ * For some examples on how to use the exception construct, please see:
+ * - @ref page_pjlib_samples_except_c
+ * - @ref page_pjlib_exception_test
+ */
+
+/**
+ * Allocate a unique exception id.
+ * Applications don't have to allocate a unique exception ID before using
+ * the exception construct. However, by doing so it ensures that there is
+ * no collisions of exception ID.
+ *
+ * As a bonus, when exception number is acquired through this function,
+ * the library can assign name to the exception (only if
+ * PJ_HAS_EXCEPTION_NAMES is enabled (default is yes)) and find out the
+ * exception name when it catches an exception.
+ *
+ * @param name Name to be associated with the exception ID.
+ * @param id Pointer to receive the ID.
+ *
+ * @return PJ_SUCCESS on success or PJ_ETOOMANY if the library
+ * is running out out ids.
+ */
+PJ_DECL(pj_status_t) pj_exception_id_alloc(const char *name,
+ pj_exception_id_t *id);
+
+/**
+ * Free an exception id.
+ *
+ * @param id The exception ID.
+ *
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_exception_id_free(pj_exception_id_t id);
+
+/**
+ * Retrieve name associated with the exception id.
+ *
+ * @param id The exception ID.
+ *
+ * @return The name associated with the specified ID.
+ */
+PJ_DECL(const char*) pj_exception_id_name(pj_exception_id_t id);
+
+
+/** @} */
+
+/**
+ * This structure (which should be invisible to user) manages the TRY handler
+ * stack.
+ */
+struct pj_exception_state_t
+{
+ struct pj_exception_state_t *prev; /**< Previous state in the list. */
+ pj_jmp_buf state; /**< jmp_buf. */
+};
+
+/**
+ * Throw exception.
+ * @param id Exception Id.
+ */
+PJ_DECL_NO_RETURN(void)
+pj_throw_exception_(pj_exception_id_t id) PJ_ATTR_NORETURN;
+
+/**
+ * Push exception handler.
+ */
+PJ_DECL(void) pj_push_exception_handler_(struct pj_exception_state_t *rec);
+
+/**
+ * Pop exception handler.
+ */
+PJ_DECL(void) pj_pop_exception_handler_(void);
+
+/**
+ * Declare that the function will use exception.
+ * @hideinitializer
+ */
+#define PJ_USE_EXCEPTION struct pj_exception_state_t pj_x_except__; int pj_x_code__
+
+/**
+ * Start exception specification block.
+ * @hideinitializer
+ */
+#define PJ_TRY if (1) { \
+ pj_push_exception_handler_(&pj_x_except__); \
+ pj_x_code__ = pj_setjmp(pj_x_except__.state); \
+ if (pj_x_code__ == 0)
+/**
+ * Catch the specified exception Id.
+ * @param id The exception number to catch.
+ * @hideinitializer
+ */
+#define PJ_CATCH(id) else if (pj_x_code__ == (id))
+
+/**
+ * Catch any exception number.
+ * @hideinitializer
+ */
+#define PJ_DEFAULT else
+
+/**
+ * End of exception specification block.
+ * @hideinitializer
+ */
+#define PJ_END pj_pop_exception_handler_(); \
+ } else {}
+
+/**
+ * Throw exception.
+ * @param exception_id The exception number.
+ * @hideinitializer
+ */
+#define PJ_THROW(exception_id) pj_throw_exception_(exception_id)
+
+/**
+ * Get current exception.
+ * @return Current exception code.
+ * @hideinitializer
+ */
+#define PJ_GET_EXCEPTION() (pj_x_code__)
+
+PJ_END_DECL
+
+
+
+#endif /* __PJ_EXCEPTION_H__ */
+
+