Skip to content

Commit

Permalink
Merge branch 'staging'
Browse files Browse the repository at this point in the history
  • Loading branch information
achakravarti committed Jan 30, 2019
2 parents fd488be + 4194b60 commit fd0f450
Showing 1 changed file with 208 additions and 0 deletions.
208 changes: 208 additions & 0 deletions inc/error.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
/******************************************************************************
* SOL LIBRARY v0.1.0+41
*
* File: sol/inc/error.h
*
* Description:
* This file is part of the API of the Sol Library. It declares the
* interface of the exception handling module.
*
* Authors:
* Abhishek Chakravarti <abhishek@taranjali.org>
*
* Copyright:
* (c) 2019 Abhishek Chakravarti
* <abhishek@taranjali.org>
*
* License:
* Released under the GNU General Public License version 3 (GPLv3)
* <http://opensource.org/licenses/GPL-3.0>. See the accompanying LICENSE
* file for complete licensing details.
*
* BY CONTINUING TO USE AND/OR DISTRIBUTE THIS FILE, YOU ACKNOWLEDGE THAT
* YOU HAVE UNDERSTOOD THESE LICENSE TERMS AND ACCEPT THEM.
******************************************************************************/





#if !defined __SOL_EXCEPTION_HANDLING_MODULE
#define __SOL_EXCEPTION_HANDLING_MODULE




#include <stddef.h>




/*
* sol_erno - generic error code
*
* The sol_erno concrete data type is used to hold error codes. Error codes
* may be defined by client code as unsigned integers, with the exception
* of the error codes defined below. This type aligns itself to the native
* word size of its compilation environment. Any function returning this
* type can take advantage of the exception handling features provided by
* this module.
*/
typedef size_t sol_erno;




/*
* SOL_ERNO_NULL - no error
*
* The SOL_ERNO_NULL symbolic constant indicates that no error has
* occurred. This error code is reserved by the Sol Library, and should
* **not** be redefined by client code. Functions that take advantage of
* the try-catch mechanism implemented by this module (through the SOL_TRY
* and SOL_CATCH labels) return this symbolic constant by default if they
* don't encounter any errors during execution.
*/
#define SOL_ERNO_NULL ((sol_erno) 0x0)




/*
* SOL_TRY - start of try block
*
* The SOL_TRY label identifies the starting point of the try block within
* a function that returns a sol_erno value. The try block contains the
* normal flow of code that may throw exceptions. It must be placed at the
* beginning of the function body, right after declaring any required local
* variables and constants, and terminated by a SOL_CATCH block.
*
* The code that may throw exceptions within this block must be tested
* through the sol_assert() and sol_try() macros defined below. In case an
* exception occurs, then control is passed to the adjacent SOL_CATCH
* block without executing the remaining code in the try block.
*
* If no error occurs, then control automatically returns to the calling
* function with a SOL_ERNO_NULL error code; there is no need for client
* code to place an explicit return statement.
*/
#define SOL_TRY \
register sol_erno __sol_erno = SOL_ERNO_NULL; \
__SOL_TRY




/*
* SOL_CATCH - start of catch block
*
* The SOL_CATCH label identifies the starting point of a catch block
* within a function that returns a sol_erno value. The catch block
* contains the error handling code, and must be placed immediately at the
* end of a SOL_TRY block.
*
* The SOL_CATCH block must be terminated by a call to the sol_throw()
* macro defined below in order to throw the current error code back to the
* calling function. At no point should the sol_assert() and sol_try()
* macros be used in the SOL_CATCH block, as this would potentially lead to
* an infinite loop.
*/
#define SOL_CATCH \
return SOL_ERNO_NULL; \
__SOL_CATCH




/*
* sol_throw() - throws current error code
*
* The sol_throw() macro throws the current error code back to the calling
* function. This macro should only be invoked at the end of a SOL_CATCH
* block after all error handling code has been excecuted. Terminating
* catch blocks with this macro helps to unwind exceptions up the call
* stack.
*
* Return:
* - SOL_ERNO_NULL if no error has occured
* - The current error code if an error has occured
*/
#define /* sol_erno */ sol_throw(/* void */) \
return __sol_erno




/*
* sol_erno_now() - gets current error code
*
* The sol_erno_now() macro returns the current sol_erno error code within
* the context of the thread in which it is called. This macro is designed
* to be used primarily within SOL_CATCH blocks, but if required, may also
* be used within SOL_TRY blocks.
*
* Return:
* - SOL_ERNO if no error has occured
* - The current error code if an error has occured
*/
#define /* const sol_erno */ sol_erno_now(/* void */) \
((const sol_erno) __sol_erno)




/*
* sol_assert() - verifies precondition
* - p: precondition predicate being asserted
* - e: error code to be thrown if assertion fails
*
* The sol_assert() macro verifies whether a precondition, expressed as a
* predicate @p, is true before any further processing takes place. This
* macro can only be called within a SOL_TRY block. If the assertion fails,
* then a sol_erno error code @e is thrown and control jumps to the
* adjacent SOL_CATCH block. This macro should **never** be called within a
* SOL_CATCH block as it may potentially lead to an infinite loop.
*/
#define /* void */ sol_assert(p, /* sol_erno */ e) \
do { \
if (!(p)) { \
__sol_erno = (e); \
goto __SOL_CATCH: \
} \
} while (0)




/*
* sol_try() - validates postcondition
* - p: postcondition being evaluated
*
* The sol_try() macro validates whether a postcondition @p, expressed as a
* function returning a sol_erno value, has not failed. The function is
* deemed to have run successfully if it has not thrown any exception as
* flagged by the returned error code. This macro can only be called within
* a SOL_TRY block. If the validation fails, then control will jump to the
* adjacent SOL_CATCH block. As with the sol_assert() macro, this macro
* should **never** be called within a SOL_CATCH block as it may
* potentially lead to an infinite loop.
*/
#define /* void */ sol_try(p) \
do { \
if ((__sol_erno = (p))) \
goto __SOL_CATCH; \
} while (0)




#endif /* !defined __SOL_EXCEPTION_HANDLING_MODULE */




/******************************************************************************
* EOF
* Built on hyperion [Tue Jan 29 02:37:24 UTC 2019]
******************************************************************************/

0 comments on commit fd0f450

Please sign in to comment.