/* *@@sourcefile ensure.h: * header file for solid code support. * * This header contains a set of helpers macros to help writing * solid code. * * You can only use those macros in functions that have a * return type of APIRET. * * Depending on whether a possible action requires additionnal * cleanup or not, you can choose between two sets of macros. * * If no extra cleanup is necessary, the simple ENSURE_OK, * ENSURE(call) and ENSURE_FAIL(rc) can be freely used. * * ENSURE_OK simply ends the execution of the function and * returns NO_ERROR. * * ENSURE(call) ends the execution of the function if call is * not NO_ERROR. Otherwise, nothing occurs. * * ENSURE_FAIL(rc) ends the execution of the function and * returns rc. * * If some extra cleanup is required (say, dynamically allocated * memory, etc.), then you must use ENSURE_BEGIN, ENSURE_SAFE(call), * ENSURE_SAFEFAIL(rc), ENSURE_FINALLY, and ENSURE_END. * * Those macros must be used in a block. The block has to start * with ENSURE_BEGIN, and must end with ENSURE_FINALLY ... ENSURE_END. * * Here is an example: * + APIRET foo(...) + { + ENSURE_BEGIN; + ... + + ENSURE_SAFE(bar()); + ... + + ENSURE_FINALLY; + // cleanup code + ... + ENSURE_END; + } * * The ENSURE_SAFE(call ) is the safe ENSURE(call) equivalent, and * ENSURE_SAFEFAIL(rc) is the safe ENSURE_FAIL(rc) equivalent. * * The cleanup code is only executed if ENSURE_SAFEFAIL has been * called or if ENSURE_SAFE(call) resulted in call returning * something that is not NO_ERROR. * * Note: Version numbering in this file relates to XWorkplace version * numbering. * *@@include #include "helpers\ensure.h" */ /* This file Copyright (C) 2001 Martin Lafaix. * * This file is part of the "XWorkplace helpers" source package. * This 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, in version 2 as it comes in the * "COPYING" file of the XWorkplace main distribution. * 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. */ #if __cplusplus extern "C" { #endif #ifndef ENSURE_HEADER_INCLUDED #define ENSURE_HEADER_INCLUDED #define ENSURE_OK return (NO_ERROR) #define ENSURE_FAIL(rc) return (rc) #define ENSURE(call) { APIRET __ensure_rc = call; \ if (__ensure_rc != NO_ERROR) \ return (__ensure_rc); } #define ENSURE_BEGIN APIRET __ensuresafe_rc = NO_ERROR #define ENSURE_FINALLY ENSURE_SAFEBLOCK: ; \ if (__ensuresafe_rc != NO_ERROR) \ { #define ENSURE_END return (__ensuresafe_rc); } #define ENSURE_SAFE(call) { __ensuresafe_rc = call; \ if (__ensuresafe_rc != NO_ERROR) \ goto ENSURE_SAFEBLOCK; } #define ENSURE_SAFEFAIL(rc) { __ensuresafe_rc = rc; goto ENSURE_SAFEBLOCK; } #endif #if __cplusplus } #endif