commit 152f2ba8079ffb892e3537b4c2abd056b1c6520e from: Sergey Bronnikov via: Sergey Bronnikov date: Thu Oct 12 13:36:22 2023 UTC Update helpers commit - c1553860d3a74b163109fb7d1b6fef272661da65 commit + 152f2ba8079ffb892e3537b4c2abd056b1c6520e blob - dfb3df6ea5f87854c250e382822e608aa1f66b73 blob + 12e0e7b49598afc24733157e05d339314baa87ae --- helpers.h +++ helpers.h @@ -1,14 +1,73 @@ /** + * See helpers: * https://nullprogram.com/blog/2023/10/08/ * https://github.com/x509cert/banned/blob/master/banned.h * https://github.com/sharkdp/dbg-macro */ -#define assert(c) while (!(c)) __builtin_unreachable() +#include +#define assert(c) while (!(c)) __builtin_unreachable() + void print_hex(const char *s) { while(*s) say_warn("(%02x)", (unsigned int) *s++); say_warn("\n"); } + +/* + * Programming by Contract is a programming methodology + * which binds the caller and the function called to a + * contract. The contract is represented using Hoare Triple: + * {P} C {Q} + * where {P} is the precondition before executing command C, + * and {Q} is the postcondition. + * + * See also: + * http://en.wikipedia.org/wiki/Design_by_contract + * http://en.wikipedia.org/wiki/Hoare_logic + * http://dlang.org/dbc.html + * + * This is an _extremely_ simple example: + * + * int divide (int n, int d) + * { + * int ans; + * + * REQUIRE(d != 0); + * + * ans = n / d; + * + * // As code is added to this function throughout its lifetime, + * // ENSURE will assert that data will be returned + * // according to the contract. Again this is an + * // extremely simple example. :-D + * ENSURE( ans == (n / d) ); + * + * return ans; + * } + */ + +/* + * Checks caller responsibility against contract + */ +#define REQUIRE(cond) assert(cond) + +/* + * Checks function reponsability against contract. + */ +#define ENSURE(cond) assert(cond) + +/* + * While REQUIRE and ENSURE apply to functions, INVARIANT + * applies to classes/structs. It ensures that intances + * of the class/struct are consistent. In other words, + * that the instance has not been corrupted. + */ +#define INVARIANT(invariant_fnc) do{ (invariant_fnc) } while (0); + +#else +#define REQUIRE(cond) do { } while (0); +#define ENSURE(cond) do { } while (0); +#define INVARIANT(invariant_fnc) do{ } while (0);