Tor  0.4.7.0-alpha-dev
structvar.c
Go to the documentation of this file.
1 /* Copyright (c) 2001 Matej Pfajfar.
2  * Copyright (c) 2001-2004, Roger Dingledine.
3  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4  * Copyright (c) 2007-2021, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
6 
7 /**
8  * @file structvar.c
9  * @brief Functions to manipulate named and typed elements of
10  * a structure.
11  *
12  * These functions represent a low-level API for accessing a member of a
13  * structure. They use typedvar.c to work, and they are used in turn by the
14  * configuration system to examine and set fields in configuration objects
15  * used by individual modules.
16  *
17  * Almost no code should call these directly.
18  **/
19 
20 #include "orconfig.h"
21 #include "lib/confmgt/structvar.h"
22 #include "lib/cc/compat_compiler.h"
23 #include "lib/conf/conftypes.h"
24 #include "lib/confmgt/type_defs.h"
25 #include "lib/confmgt/typedvar.h"
26 #include "lib/log/util_bug.h"
27 
29 
30 #include <stddef.h>
31 
32 /**
33  * Return true iff all fields on <b>decl</b> are NULL or 0, indicating that
34  * there is no object or no magic number to check.
35  **/
36 static inline bool
38 {
39  return decl->typename == NULL &&
40  decl->magic_offset == 0 &&
41  decl->magic_val == 0;
42 }
43 
44 /**
45  * Set the 'magic number' on <b>object</b> to correspond to decl.
46  **/
47 void
48 struct_set_magic(void *object, const struct_magic_decl_t *decl)
49 {
50  tor_assert(decl);
51  if (magic_is_null(decl))
52  return;
53 
54  tor_assert(object);
55  uint32_t *ptr = STRUCT_VAR_P(object, decl->magic_offset);
56  *ptr = decl->magic_val;
57 }
58 
59 /**
60  * Assert that the 'magic number' on <b>object</b> to corresponds to decl.
61  **/
62 void
63 struct_check_magic(const void *object, const struct_magic_decl_t *decl)
64 {
65  tor_assert(decl);
66  if (magic_is_null(decl))
67  return;
68 
69  tor_assert(object);
70 
71  const uint32_t *ptr = STRUCT_VAR_P(object, decl->magic_offset);
72  tor_assertf(*ptr == decl->magic_val,
73  "Bad magic number on purported %s object. "
74  "Expected %"PRIu32"x but got %"PRIu32"x.",
75  decl->typename, decl->magic_val, *ptr);
76 }
77 
78 /**
79  * Return a mutable pointer to the member of <b>object</b> described
80  * by <b>member</b>.
81  **/
82 void *
83 struct_get_mptr(void *object, const struct_member_t *member)
84 {
85  tor_assert(object);
86  return STRUCT_VAR_P(object, member->offset);
87 }
88 
89 /**
90  * Return a const pointer to the member of <b>object</b> described
91  * by <b>member</b>.
92  **/
93 const void *
94 struct_get_ptr(const void *object, const struct_member_t *member)
95 {
96  tor_assert(object);
97  return STRUCT_VAR_P(object, member->offset);
98 }
99 
100 /**
101  * Helper: given a struct_member_t, look up the type definition for its
102  * variable.
103  */
104 static const var_type_def_t *
106 {
107  if (member->type_def)
108  return member->type_def;
109 
110  return lookup_type_def(member->type);
111 }
112 
113 /**
114  * (As typed_var_free, but free and clear the member of <b>object</b> defined
115  * by <b>member</b>.)
116  **/
117 void
118 struct_var_free(void *object, const struct_member_t *member)
119 {
120  void *p = struct_get_mptr(object, member);
121  const var_type_def_t *def = get_type_def(member);
122 
123  typed_var_free(p, def);
124 }
125 
126 /**
127  * (As typed_var_copy, but copy from <b>src</b> to <b>dest</b> the member
128  * defined by <b>member</b>.)
129  **/
130 int
131 struct_var_copy(void *dest, const void *src, const struct_member_t *member)
132 {
133  void *p_dest = struct_get_mptr(dest, member);
134  const void *p_src = struct_get_ptr(src, member);
135  const var_type_def_t *def = get_type_def(member);
136 
137  return typed_var_copy(p_dest, p_src, def);
138 }
139 
140 /**
141  * (As typed_var_eq, but compare the members of <b>a</b> and <b>b</b>
142  * defined by <b>member</b>.)
143  **/
144 bool
145 struct_var_eq(const void *a, const void *b, const struct_member_t *member)
146 {
147  const void *p_a = struct_get_ptr(a, member);
148  const void *p_b = struct_get_ptr(b, member);
149  const var_type_def_t *def = get_type_def(member);
150 
151  return typed_var_eq(p_a, p_b, def);
152 }
153 
154 /**
155  * (As typed_var_ok, but validate the member of <b>object</b> defined by
156  * <b>member</b>.)
157  **/
158 bool
159 struct_var_ok(const void *object, const struct_member_t *member)
160 {
161  const void *p = struct_get_ptr(object, member);
162  const var_type_def_t *def = get_type_def(member);
163 
164  return typed_var_ok(p, def);
165 }
166 
167 /**
168  * (As typed_var_kvassign, but assign a value to the member of <b>object</b>
169  * defined by <b>member</b>.)
170  **/
171 int
172 struct_var_kvassign(void *object, const struct config_line_t *line,
173  char **errmsg,
174  const struct_member_t *member)
175 {
176  void *p = struct_get_mptr(object, member);
177  const var_type_def_t *def = get_type_def(member);
178 
179  return typed_var_kvassign(p, line, errmsg, def);
180 }
181 
182 /**
183  * (As typed_var_kvencode, but encode the value of the member of <b>object</b>
184  * defined by <b>member</b>.)
185  **/
186 struct config_line_t *
187 struct_var_kvencode(const void *object, const struct_member_t *member)
188 {
189  const void *p = struct_get_ptr(object, member);
190  const var_type_def_t *def = get_type_def(member);
191 
192  return typed_var_kvencode(member->name, p, def);
193 }
194 
195 /**
196  * Mark the field in <b>object</b> determined by <b>member</b> -- a variable
197  * that ordinarily would be extended by assignment -- as "fragile", so that it
198  * will get replaced by the next assignment instead.
199  */
200 void
201 struct_var_mark_fragile(void *object, const struct_member_t *member)
202 {
203  void *p = struct_get_mptr(object, member);
204  const var_type_def_t *def = get_type_def(member);
205  return typed_var_mark_fragile(p, def);
206 }
207 
208 /**
209  * Return the official name of this struct member.
210  **/
211 const char *
213 {
214  return member->name;
215 }
216 
217 /**
218  * Return the type name for this struct member.
219  *
220  * Do not use the output of this function to inspect a type within Tor. It is
221  * suitable for debugging, informing the controller or user of a variable's
222  * type, etc.
223  **/
224 const char *
226 {
227  const var_type_def_t *def = get_type_def(member);
228 
229  return def ? def->name : NULL;
230 }
231 
232 /** Return all of the flags set for this struct member. */
233 uint32_t
235 {
236  const var_type_def_t *def = get_type_def(member);
237 
238  return def ? def->flags : 0;
239 }
Utility macros to handle different features and behavior in different compilers.
#define STRUCT_VAR_P(st, off)
Types used to specify configurable options.
ptrdiff_t magic_offset
Definition: conftypes.h:145
const char * typename
Definition: conftypes.h:140
uint32_t magic_val
Definition: conftypes.h:142
ptrdiff_t offset
Definition: conftypes.h:125
const struct var_type_def_t * type_def
Definition: conftypes.h:120
const char * name
Definition: conftypes.h:98
config_type_t type
Definition: conftypes.h:114
void struct_set_magic(void *object, const struct_magic_decl_t *decl)
Definition: structvar.c:48
const void * struct_get_ptr(const void *object, const struct_member_t *member)
Definition: structvar.c:94
const char * struct_var_get_typename(const struct_member_t *member)
Definition: structvar.c:225
void * struct_get_mptr(void *object, const struct_member_t *member)
Definition: structvar.c:83
void struct_check_magic(const void *object, const struct_magic_decl_t *decl)
Definition: structvar.c:63
bool struct_var_eq(const void *a, const void *b, const struct_member_t *member)
Definition: structvar.c:145
int struct_var_kvassign(void *object, const struct config_line_t *line, char **errmsg, const struct_member_t *member)
Definition: structvar.c:172
int struct_var_copy(void *dest, const void *src, const struct_member_t *member)
Definition: structvar.c:131
void struct_var_free(void *object, const struct_member_t *member)
Definition: structvar.c:118
void struct_var_mark_fragile(void *object, const struct_member_t *member)
Definition: structvar.c:201
bool struct_var_ok(const void *object, const struct_member_t *member)
Definition: structvar.c:159
struct config_line_t * struct_var_kvencode(const void *object, const struct_member_t *member)
Definition: structvar.c:187
static bool magic_is_null(const struct_magic_decl_t *decl)
Definition: structvar.c:37
static const var_type_def_t * get_type_def(const struct_member_t *member)
Definition: structvar.c:105
uint32_t struct_var_get_flags(const struct_member_t *member)
Definition: structvar.c:234
const char * struct_var_get_name(const struct_member_t *member)
Definition: structvar.c:212
Header for lib/confmgt/structvar.c.
const char * name
const var_type_def_t * lookup_type_def(config_type_t type)
Definition: type_defs.c:842
Header for lib/confmgt/type_defs.c.
void typed_var_mark_fragile(void *value, const var_type_def_t *def)
Definition: typedvar.c:228
void typed_var_free(void *target, const var_type_def_t *def)
Definition: typedvar.c:95
config_line_t * typed_var_kvencode(const char *key, const void *value, const var_type_def_t *def)
Definition: typedvar.c:129
bool typed_var_eq(const void *a, const void *b, const var_type_def_t *def)
Definition: typedvar.c:187
bool typed_var_ok(const void *value, const var_type_def_t *def)
Definition: typedvar.c:211
int typed_var_kvassign(void *target, const config_line_t *line, char **errmsg, const var_type_def_t *def)
Definition: typedvar.c:67
int typed_var_copy(void *dest, const void *src, const var_type_def_t *def)
Definition: typedvar.c:154
Header for lib/confmgt/typedvar.c.
Macros to manage assertions, fatal and non-fatal.
#define tor_assert(expr)
Definition: util_bug.h:102
Structure declarations for typedvar type definitions.