| 1 |  | 
|---|
| 2 | /* | 
|---|
| 3 | *@@sourcefile ensure.h: | 
|---|
| 4 | *      header file for solid code support. | 
|---|
| 5 | * | 
|---|
| 6 | *      This header contains a set of helpers macros to help writing | 
|---|
| 7 | *      solid code. | 
|---|
| 8 | * | 
|---|
| 9 | *      You can only use those macros in functions that have a | 
|---|
| 10 | *      return type of APIRET. | 
|---|
| 11 | * | 
|---|
| 12 | *      Depending on whether a possible action requires additionnal | 
|---|
| 13 | *      cleanup or not, you can choose between two sets of macros. | 
|---|
| 14 | * | 
|---|
| 15 | *      If no extra cleanup is necessary, the simple ENSURE_OK, | 
|---|
| 16 | *      ENSURE(call) and ENSURE_FAIL(rc) can be freely used. | 
|---|
| 17 | * | 
|---|
| 18 | *      ENSURE_OK simply ends the execution of the function and | 
|---|
| 19 | *      returns NO_ERROR. | 
|---|
| 20 | * | 
|---|
| 21 | *      ENSURE(call) ends the execution of the function if call is | 
|---|
| 22 | *      not NO_ERROR.  Otherwise, nothing occurs. | 
|---|
| 23 | * | 
|---|
| 24 | *      ENSURE_FAIL(rc) ends the execution of the function and | 
|---|
| 25 | *      returns rc. | 
|---|
| 26 | * | 
|---|
| 27 | *      If some extra cleanup is required (say, dynamically allocated | 
|---|
| 28 | *      memory, etc.), then you must use ENSURE_BEGIN, ENSURE_SAFE(call), | 
|---|
| 29 | *      ENSURE_SAFEFAIL(rc), ENSURE_FINALLY, and ENSURE_END. | 
|---|
| 30 | * | 
|---|
| 31 | *      Those macros must be used in a block.  The block has to start | 
|---|
| 32 | *      with ENSURE_BEGIN, and must end with ENSURE_FINALLY ... ENSURE_END. | 
|---|
| 33 | * | 
|---|
| 34 | *      Here is an example: | 
|---|
| 35 | * | 
|---|
| 36 | +      APIRET foo(...) | 
|---|
| 37 | +      { | 
|---|
| 38 | +          ENSURE_BEGIN; | 
|---|
| 39 | +          ... | 
|---|
| 40 | + | 
|---|
| 41 | +          ENSURE_SAFE(bar()); | 
|---|
| 42 | +          ... | 
|---|
| 43 | + | 
|---|
| 44 | +          ENSURE_FINALLY; | 
|---|
| 45 | +              // cleanup code | 
|---|
| 46 | +              ... | 
|---|
| 47 | +          ENSURE_END; | 
|---|
| 48 | +      } | 
|---|
| 49 | * | 
|---|
| 50 | *      The ENSURE_SAFE(call ) is the safe ENSURE(call) equivalent, and | 
|---|
| 51 | *      ENSURE_SAFEFAIL(rc) is the safe ENSURE_FAIL(rc) equivalent. | 
|---|
| 52 | * | 
|---|
| 53 | *      The cleanup code is only executed if ENSURE_SAFEFAIL has been | 
|---|
| 54 | *      called or if ENSURE_SAFE(call) resulted in call returning | 
|---|
| 55 | *      something that is not NO_ERROR. | 
|---|
| 56 | * | 
|---|
| 57 | *      Note: Version numbering in this file relates to XWorkplace version | 
|---|
| 58 | *            numbering. | 
|---|
| 59 | * | 
|---|
| 60 | *@@include #include "helpers\ensure.h" | 
|---|
| 61 | */ | 
|---|
| 62 |  | 
|---|
| 63 | /*      This file Copyright (C) 2001 Martin Lafaix. | 
|---|
| 64 | * | 
|---|
| 65 | *      This file is part of the "XWorkplace helpers" source package. | 
|---|
| 66 | *      This is free software; you can redistribute it and/or modify | 
|---|
| 67 | *      it under the terms of the GNU General Public License as published | 
|---|
| 68 | *      by the Free Software Foundation, in version 2 as it comes in the | 
|---|
| 69 | *      "COPYING" file of the XWorkplace main distribution. | 
|---|
| 70 | *      This program is distributed in the hope that it will be useful, | 
|---|
| 71 | *      but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|---|
| 72 | *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|---|
| 73 | *      GNU General Public License for more details. | 
|---|
| 74 | */ | 
|---|
| 75 |  | 
|---|
| 76 | #if __cplusplus | 
|---|
| 77 | extern "C" { | 
|---|
| 78 | #endif | 
|---|
| 79 |  | 
|---|
| 80 | #ifndef ENSURE_HEADER_INCLUDED | 
|---|
| 81 | #define ENSURE_HEADER_INCLUDED | 
|---|
| 82 |  | 
|---|
| 83 | #define ENSURE_OK            return (NO_ERROR) | 
|---|
| 84 | #define ENSURE_FAIL(rc)      return (rc) | 
|---|
| 85 | #define ENSURE(call)         { APIRET __ensure_rc = call; \ | 
|---|
| 86 | if (__ensure_rc != NO_ERROR) \ | 
|---|
| 87 | return (__ensure_rc); } | 
|---|
| 88 |  | 
|---|
| 89 | #define ENSURE_BEGIN         APIRET __ensuresafe_rc = NO_ERROR | 
|---|
| 90 |  | 
|---|
| 91 | #define ENSURE_FINALLY       ENSURE_SAFEBLOCK: ; \ | 
|---|
| 92 | if (__ensuresafe_rc != NO_ERROR) \ | 
|---|
| 93 | { | 
|---|
| 94 |  | 
|---|
| 95 | #define ENSURE_END           return (__ensuresafe_rc); } | 
|---|
| 96 |  | 
|---|
| 97 | #define ENSURE_SAFE(call)    { __ensuresafe_rc = call; \ | 
|---|
| 98 | if (__ensuresafe_rc != NO_ERROR) \ | 
|---|
| 99 | goto ENSURE_SAFEBLOCK; } | 
|---|
| 100 |  | 
|---|
| 101 | #define ENSURE_SAFEFAIL(rc)  { __ensuresafe_rc = rc; goto ENSURE_SAFEBLOCK; } | 
|---|
| 102 | #endif | 
|---|
| 103 |  | 
|---|
| 104 | #if __cplusplus | 
|---|
| 105 | } | 
|---|
| 106 | #endif | 
|---|
| 107 |  | 
|---|