/* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** * @file conftesting.h * @brief Macro and type declarations for testing **/ #ifndef TOR_LIB_CONF_CONFTESTING_H #define TOR_LIB_CONF_CONFTESTING_H #ifdef TOR_UNIT_TESTS /** * Union used when building in test mode typechecking the members of a type * used with confparse.c. See CONF_CHECK_VAR_TYPE for a description of how * it is used. */ typedef union { char **STRING; char **FILENAME; int *POSINT; /* yes, this is really an int, and not an unsigned int. For * historical reasons, many configuration values are restricted * to the range [0,INT_MAX], and stored in signed ints. */ uint64_t *UINT64; int *INT; int *INTERVAL; int *MSEC_INTERVAL; uint64_t *MEMUNIT; double *DOUBLE; int *BOOL; int *AUTOBOOL; time_t *ISOTIME; struct smartlist_t **CSV; int *CSV_INTERVAL; struct config_line_t **LINELIST; struct config_line_t **LINELIST_S; struct config_line_t **LINELIST_V; // XXXX this doesn't belong at this level of abstraction. struct routerset_t **ROUTERSET; } confparse_dummy_values_t; #endif /* defined(TOR_UNIT_TESTS) */ /* Macros to define extra members inside config_var_t fields, and at the * end of a list of them. */ #ifdef TOR_UNIT_TESTS /* This is a somewhat magic type-checking macro for users of confparse.c. * It initializes a union member "confparse_dummy_values_t.conftype" with * the address of a static member "tp_dummy.member". This * will give a compiler warning unless the member field is of the correct * type. * * (This warning is mandatory, because a type mismatch here violates the type * compatibility constraint for simple assignment, and requires a diagnostic, * according to the C spec.) * * For example, suppose you say: * "CONF_CHECK_VAR_TYPE(or_options_t, STRING, Address)". * Then this macro will evaluate to: * { .STRING = &or_options_t_dummy.Address } * And since confparse_dummy_values_t.STRING has type "char **", that * expression will create a warning unless or_options_t.Address also * has type "char *". */ #define CONF_CHECK_VAR_TYPE(tp, conftype, member) \ { . conftype = &tp ## _dummy . member } #define CONF_TEST_MEMBERS(tp, conftype, member) \ , .var_ptr_dummy=CONF_CHECK_VAR_TYPE(tp, conftype, member) #define DUMMY_CONF_TEST_MEMBERS , .var_ptr_dummy={ .INT=NULL } #define DUMMY_TYPECHECK_INSTANCE(tp) \ static tp tp ## _dummy #else /* !defined(TOR_UNIT_TESTS) */ #define CONF_TEST_MEMBERS(tp, conftype, member) /* Repeatedly declarable incomplete struct to absorb redundant semicolons */ #define DUMMY_TYPECHECK_INSTANCE(tp) \ struct tor_semicolon_eater #define DUMMY_CONF_TEST_MEMBERS #endif /* defined(TOR_UNIT_TESTS) */ #endif /* !defined(TOR_LIB_CONF_CONFTESTING_H) */