|  | @@ -40,6 +40,36 @@ typedef enum config_type_t {
 | 
	
		
			
				|  |  |    CONFIG_TYPE_OBSOLETE,     /**< Obsolete (ignored) option. */
 | 
	
		
			
				|  |  |  } config_type_t;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +#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 *UINT; /* yes, really: Even though the confparse type is called
 | 
	
		
			
				|  |  | +              * "UINT", it still uses the C int type -- it just enforces that
 | 
	
		
			
				|  |  | +              * the values are in range [0,INT_MAX].
 | 
	
		
			
				|  |  | +              */
 | 
	
		
			
				|  |  | +  int *INT;
 | 
	
		
			
				|  |  | +  int *PORT;
 | 
	
		
			
				|  |  | +  int *INTERVAL;
 | 
	
		
			
				|  |  | +  int *MSEC_INTERVAL;
 | 
	
		
			
				|  |  | +  uint64_t *MEMUNIT;
 | 
	
		
			
				|  |  | +  double *DOUBLE;
 | 
	
		
			
				|  |  | +  int *BOOL;
 | 
	
		
			
				|  |  | +  int *AUTOBOOL;
 | 
	
		
			
				|  |  | +  time_t *ISOTIME;
 | 
	
		
			
				|  |  | +  smartlist_t **CSV;
 | 
	
		
			
				|  |  | +  smartlist_t **CSV_INTERVAL;
 | 
	
		
			
				|  |  | +  config_line_t **LINELIST;
 | 
	
		
			
				|  |  | +  config_line_t **LINELIST_S;
 | 
	
		
			
				|  |  | +  config_line_t **LINELIST_V;
 | 
	
		
			
				|  |  | +  routerset_t **ROUTERSET;
 | 
	
		
			
				|  |  | +} confparse_dummy_values_t;
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  /** An abbreviation for a configuration option allowed on the command line. */
 | 
	
		
			
				|  |  |  typedef struct config_abbrev_t {
 | 
	
		
			
				|  |  |    const char *abbreviated;
 | 
	
	
		
			
				|  | @@ -64,8 +94,50 @@ typedef struct config_var_t {
 | 
	
		
			
				|  |  |                         * value. */
 | 
	
		
			
				|  |  |    off_t var_offset; /**< Offset of the corresponding member of or_options_t. */
 | 
	
		
			
				|  |  |    const char *initvalue; /**< String (or null) describing initial value. */
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +#ifdef TOR_UNIT_TESTS
 | 
	
		
			
				|  |  | +  /** Used for compiler-magic to typecheck the corresponding field in the
 | 
	
		
			
				|  |  | +   * corresponding struct. Only used in unit test mode, at compile-time. */
 | 
	
		
			
				|  |  | +  confparse_dummy_values_t var_ptr_dummy;
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  |  } config_var_t;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +/* 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) \
 | 
	
		
			
				|  |  | +  , CONF_CHECK_VAR_TYPE(tp, conftype, member)
 | 
	
		
			
				|  |  | +#define END_OF_CONFIG_VARS                                      \
 | 
	
		
			
				|  |  | +  { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL, { .INT=NULL } }
 | 
	
		
			
				|  |  | +#define DUMMY_TYPECHECK_INSTANCE(tp)            \
 | 
	
		
			
				|  |  | +  static tp tp ## _dummy
 | 
	
		
			
				|  |  | +#else
 | 
	
		
			
				|  |  | +#define CONF_TEST_MEMBERS(tp, conftype, member)
 | 
	
		
			
				|  |  | +#define END_OF_CONFIG_VARS { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
 | 
	
		
			
				|  |  | +#define DUMMY_TYPECHECK_INSTANCE(tp)
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  /** Type of a callback to validate whether a given configuration is
 | 
	
		
			
				|  |  |   * well-formed and consistent. See options_trial_assign() for documentation
 | 
	
		
			
				|  |  |   * of arguments. */
 |