Commit 339178b2 authored by Peter Hutterer's avatar Peter Hutterer Committed by Rusty Russell

argcheck: a module to check argument ranges

This code provides some macros to check arguments for valid value ranges.
Consider this a mild version of assert(3), because all it does is to log
a message and continue.

These macros don't replace error handling, but they are useful in
situations where an error is unexpected but not common, i.e.
this shouldn't happen but if it does let me know".
Signed-off-by: default avatarPeter Hutterer <peter.hutterer@who-t.net>
parent 95b59482
......@@ -8,6 +8,7 @@ CFLAGS = $(CCAN_CFLAGS) -I. $(DEPGEN)
# Modules which are just a header:
MODS_NO_SRC := alignof \
argcheck \
array_size \
asearch \
bitmap \
......
../../licenses/BSD-MIT
\ No newline at end of file
#include "config.h"
/**
* argcheck - macros to check arguments at runtime
*
* This code provides some macros to check arguments for valid value ranges.
* Consider this a mild version of assert(3), because all it does is to log
* a message and continue.
*
* These macros don't replace error handling, but they are useful in
* situations where an error is unexpected but not common, i.e.
* "this shouldn't happen but if it does let me know".
*
* argcheck's error messages can be disabled by defining
* ARGCHECK_DISABLE_LOGGING before including the header file. The conditions
* will continue to evaluate but no error messages will be generated. It is thus
* safe to use argcheck macros inside if conditions.
*
* By default, argcheck prints to fprintf(stderr). That can be changed by
* defining argcheck_log to a custom log function. See argcheck_log_() for the
* function signature. If ARGCHECK_DISABLE_LOGGING is defined, the custom log
* function is not called.
*
* Example:
* #include <stdio.h>
* #include <ccan/argcheck/argcheck.h>
*
* enum state { S1, S2, S3 };
*
* static int some_state_machine(enum state s) {
* int b;
*
* argcheck_int_range(s, S1, S3);
*
* switch(s) {
* case S1: b = 8; break;
* case S2: b = 9; break;
* case S3: b = 88; break;
* default:
* break;
* }
*
* return b;
* }
*
* int main(int argc, char *argv[]) {
* int a = S1;
*
* if (!argcheck_int_gt(argc, 1))
* return 1;
*
* return some_state_machine(a);
* }
*
* Author: Peter Hutterer <peter.hutterer@who-t.net>
* Maintainer: Peter Hutterer <peter.hutterer@who-t.net>
* License: BSD-MIT
*/
int main(int argc, char *argv[])
{
/* Expect exactly one argument */
if (argc != 2)
return 1;
if (strcmp(argv[1], "depends") == 0) {
printf("ccan/likely\n");
printf("ccan/compiler\n");
return 0;
}
return 1;
}
This diff is collapsed.
#include <ccan/tap/tap.h>
#include <stdarg.h>
#include <stdio.h>
#include <ccan/argcheck/argcheck.h>
int main(void)
{
int a = 0;
const int flag = 0x1;
const int invalid_flag = 0x0;
int *ptr = NULL,
*ptr_not_null = &a;
const char *str = "hello",
*str_zero = "\0",
*str_null = NULL;
plan_tests(60);
ok1(!argcheck_int_eq(a, 1));
ok1(argcheck_int_eq(a, 0));
ok1(!argcheck_int_ne(a, 0));
ok1(argcheck_int_ne(a, 10));
ok1(!argcheck_int_ge(a, 1));
ok1(argcheck_int_ge(a, 0));
ok1(argcheck_int_ge(a, -1));
ok1(!argcheck_int_gt(a, 1));
ok1(!argcheck_int_gt(a, 0));
ok1(argcheck_int_gt(a, -1));
ok1(!argcheck_int_le(a, -1));
ok1(argcheck_int_le(a, 0));
ok1(argcheck_int_le(a, 1));
ok1(!argcheck_int_lt(a, -1));
ok1(!argcheck_int_lt(a, 0));
ok1(argcheck_int_lt(a, 1));
ok1(!argcheck_int_range(a, 0, -1));
ok1(!argcheck_int_range(a, -3, -1));
ok1(argcheck_int_range(a, 0, 1));
ok1(argcheck_int_range(a, -1, 0));
ok1(!argcheck_flag_set(a, invalid_flag));
ok1(!argcheck_flag_set(a, flag));
ok1(argcheck_flag_set(a | flag, flag));
ok1(!argcheck_flag_unset(a, invalid_flag));
ok1(!argcheck_flag_unset(a | flag, flag));
ok1(argcheck_flag_unset(a, flag));
ok1(argcheck_ptr_null(ptr));
ok1(!argcheck_ptr_not_null(ptr));
ok1(!argcheck_ptr_null(ptr_not_null));
ok1(argcheck_ptr_not_null(ptr_not_null));
ok1(argcheck_str_null(str_null));
ok1(!argcheck_str_not_null(str_null));
ok1(!argcheck_str_null(str));
ok1(argcheck_str_not_null(str));
ok1(!argcheck_str_null(str_zero));
ok1(argcheck_str_not_null(str_zero));
ok1(!argcheck_str_zero_len(str_null));
ok1(argcheck_str_zero_len(str_zero));
ok1(!argcheck_str_zero_len(str));
ok1(!argcheck_str_not_zero_len(str_null));
ok1(!argcheck_str_not_zero_len(str_zero));
ok1(argcheck_str_not_zero_len(str));
ok1(!argcheck_str_min_len(str_null, 1));
ok1(!argcheck_str_min_len(str_zero, 1));
ok1(argcheck_str_min_len(str, 1));
ok1(!argcheck_str_max_len(str_null, 1));
ok1(argcheck_str_max_len(str_zero, 1));
ok1(!argcheck_str_max_len(str, 1));
ok1(argcheck_str_null_or_zero_len(str_null));
ok1(argcheck_str_null_or_zero_len(str_zero));
ok1(!argcheck_str_null_or_zero_len(str));
ok1(argcheck_str_null_or_not_zero_len(str_null));
ok1(!argcheck_str_null_or_not_zero_len(str_zero));
ok1(argcheck_str_null_or_not_zero_len(str));
ok1(argcheck_str_null_or_min_len(str_null, 1));
ok1(!argcheck_str_null_or_min_len(str_zero, 1));
ok1(argcheck_str_null_or_min_len(str, 1));
ok1(argcheck_str_null_or_max_len(str_null, 1));
ok1(argcheck_str_null_or_max_len(str_zero, 1));
ok1(!argcheck_str_null_or_max_len(str, 1));
return exit_status();
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment