picow-http 0.12.1-4-g9d4fd13
HTTP server for the Raspberry Pi PicoW
|
Macros | |
#define | PICOW_HTTP_ASSERT(c) |
Assert that a condition is true. More... | |
#define | AZ(x) do { PICOW_HTTP_ASSERT((x) == 0); } while (0) |
Assert that a value is zero or NULL More... | |
#define | AN(x) do { PICOW_HTTP_ASSERT((x) != 0); } while (0) |
Assert that a value is not zero, or not NULL More... | |
#define | ZERO_OBJ(to, sz) |
Set an object to all zero. More... | |
#define | INIT_OBJ(to, type_magic) |
Initialize an object with its magic number. More... | |
#define | FINI_OBJ(to) |
Finalize an object. More... | |
#define | VALID_OBJ(ptr, type_magic) ((ptr) != NULL && (ptr)->magic == (type_magic)) |
Return true if an object is valid for its type. More... | |
#define | CHECK_OBJ(ptr, type_magic) |
Assert that an object is valid for its type. More... | |
#define | CHECK_OBJ_NOTNULL(ptr, type_magic) |
Assert that a pointer is not NULL , and points to an object that is valid for its type. More... | |
#define | CHECK_OBJ_ORNULL(ptr, type_magic) |
Assert that a pointer is either NULL , or it points to an object that is valid for its type. More... | |
#define | CAST_OBJ(to, from, type_magic) |
Cast a pointer, and if not NULL , assert that it points to an object that is valid for its type. More... | |
#define | CAST_OBJ_NOTNULL(to, from, type_magic) |
Cast a pointer, and assert that it it is not NULL and points to an object that is valid for its type. More... | |
picow-http uses a set of macros to implement assertions that check against a variety of "must not ever happen" errors in debug builds, as well as some common operations for pointers to struct types. The assertions primarily check for "wild pointer" errors – NULL
dereferences or other invalid pointer values; but they can be used to check any boolean condition. Violations of an assertion cause a panic when NDEBUG
is not defined, as is the case for the CMake Debug
build type. When NDEBUG
is defined, as for CMake Release
builds, the assertions are no-ops. The intent is that errors lead to hard and fast failures during development and debugging, and then the overhead of assertions is removed when debugging is done. Since these mechanisms are sufficiently general and may be relevant for application code, they are provided in the public API.
Many of the assertions check a "magic number", the value of a struct member named magic
. The idiom is that magic
is the first member of the struct (thus at offset 0 from the struct's starting address), set to an unsigned 32-bit value specific to the struct type:
The value of a magic number is best chosen at random, and must be different for every struct type to be checked. To use the type checking code:
magic
field to the value for its type (see INIT_OBJ()).magic
field for the value expected for the type.If the magic number doesn't match, then the pointer is definitely of the wrong type. If it matches, then it's almost certainly the right type.
This code was inspired by (and much of it copied from) the Varnish cache project (see miniobj.h and the VAS interface).
#define AN | ( | x | ) | do { PICOW_HTTP_ASSERT((x) != 0); } while (0) |
If NDEBUG
is not defined, panic if x
is zero or NULL
. No-op if NDEBUG
is defined.
Example:
[in] | x | any expression. If x is a pointer, this is a check expecting non-NULL . |
#define AZ | ( | x | ) | do { PICOW_HTTP_ASSERT((x) == 0); } while (0) |
If NDEBUG
is not defined, panic unless x
is zero or NULL
. No-op if NDEBUG
is defined.
Example:
[in] | x | any expression. If x is a pointer, this is a check expecting NULL . |
#define CAST_OBJ | ( | to, | |
from, | |||
type_magic | |||
) |
Assign from
to to
, and if NDEBUG
is not defined and the pointers are not NULL
, then panic if to
points to a struct whose magic
member is not equal to type_magic
.
Example:
[in] | to | pointer to a struct type for which a magic number has been defined |
[in] | from | pointer |
[in] | type_magic | type-specific magic number constant |
#define CAST_OBJ_NOTNULL | ( | to, | |
from, | |||
type_magic | |||
) |
Assign from
to to
, and if NDEBUG
is not defined, then panic if the pointer is NULL
, or if after the cast, to
points to a struct whose magic
member is not equal to type_magic
.
Example:
[in] | to | pointer to a struct type for which a magic number has been defined |
[in] | from | pointer |
[in] | type_magic | type-specific magic number constant |
#define CHECK_OBJ | ( | ptr, | |
type_magic | |||
) |
If NDEBUG
is not defined, panic if ptr
points to a struct whose magic
member is not equal to type_magic
. No-op if NDEBUG
is defined.
Example:
[in] | ptr | pointer to a struct type for which a magic number has been defined. MAY NOT be NULL |
[in] | type_magic | type-specific magic number constant |
#define CHECK_OBJ_NOTNULL | ( | ptr, | |
type_magic | |||
) |
If NDEBUG
is not defined, panic if ptr
is NULL
, or points to a struct whose magic
member is not equal to type_magic
. No-op if NDEBUG
is defined.
Example:
[in] | ptr | pointer to a struct type for which a magic number has been defined |
[in] | type_magic | type-specific magic number constant |
#define CHECK_OBJ_ORNULL | ( | ptr, | |
type_magic | |||
) |
If NDEBUG
is not defined and ptr
is not NULL
, then panic if ptr
points to a struct whose magic
member is not equal to type_magic
. No-op if NDEBUG
is defined.
Example:
[in] | ptr | pointer to a struct type for which a magic number has been defined |
[in] | type_magic | type-specific magic number constant |
#define FINI_OBJ | ( | to | ) |
Set the magic
member of the object pointed to by to
to 0, and set to
to NULL
. This ensures that checks will fail if the code subsequently attempts to access the object.
[in] | to | pointer to a struct type for which the magic member has been defined |
#define INIT_OBJ | ( | to, | |
type_magic | |||
) |
Set the magic
member of the object pointed to by to
to type_magic
, and all other members to 0.
[in] | to | pointer to a struct type for which a magic number has been defined |
[in] | type_magic | type-specific magic number constant |
#define PICOW_HTTP_ASSERT | ( | c | ) |
If NDEBUG
is not defined, panic unless c
is true (i.e panic if c
evaluates to zero). If NDEBUG
is defined, PICOW_HTTP_ASSERT
is a no-op.
Example:
[in] | c | a boolean expression |
#define VALID_OBJ | ( | ptr, | |
type_magic | |||
) | ((ptr) != NULL && (ptr)->magic == (type_magic)) |
Example:
[in] | ptr | pointer to a struct type for which a magic number has been defined |
[in] | type_magic | type-specific magic number constant |
ptr
is not NULL
and the value of its magic
member is type_magic
#define ZERO_OBJ | ( | to, | |
sz | |||
) |
Set sz
bytes starting at address to
to 0.
[in] | to | a pointer |
[in] | sz | number of bytes (commonly from sizeof() ) |