Line data Source code
1 : #ifndef HEADER_fd_src_app_platform_fd_config_extract_h
2 : #define HEADER_fd_src_app_platform_fd_config_extract_h
3 :
4 : #include "../../util/fd_util.h"
5 : #include "../../util/fd_boolau.h"
6 : #include "../../util/pod/fd_pod.h"
7 :
8 : FD_PROTOTYPES_BEGIN
9 :
10 : /* fdctl_pod_find_leftover recursively descends a pod and logs a
11 : WARNING for each remaining leaf item. Intended for warning the user
12 : about unrecognized config options, after loading config files into a
13 : pod. */
14 :
15 : int
16 : fdctl_pod_find_leftover( uchar * pod );
17 :
18 : /* Pod query utils ****************************************************/
19 :
20 : static inline int
21 : fdctl_cfg_get_cstr_( char * out,
22 : ulong out_sz,
23 : fd_pod_info_t const * info,
24 0 : char const * path ) {
25 0 : if( FD_UNLIKELY( info->val_type != FD_POD_VAL_TYPE_CSTR ) ) {
26 0 : FD_LOG_WARNING(( "invalid value for `%s`", path ));
27 0 : return 0;
28 0 : }
29 0 : char const * str = info->val;
30 0 : ulong sz = strlen( str ) + 1;
31 0 : if( FD_UNLIKELY( sz > out_sz ) ) {
32 0 : FD_LOG_WARNING(( "`%s`: too long (max %ld)", path, (long)out_sz-1L ));
33 0 : return 0;
34 0 : }
35 0 : fd_memcpy( out, str, sz );
36 0 : return 1;
37 0 : }
38 :
39 : #define fdctl_cfg_get_cstr( out, out_sz, info, path ) \
40 : fdctl_cfg_get_cstr_( *out, out_sz, info, path )
41 :
42 : static inline int
43 : fdctl_cfg_get_ulong( ulong * out,
44 : ulong out_sz FD_PARAM_UNUSED,
45 : fd_pod_info_t const * info,
46 0 : char const * path ) {
47 :
48 0 : ulong num;
49 0 : switch( info->val_type ) {
50 0 : case FD_POD_VAL_TYPE_LONG:
51 0 : fd_ulong_svw_dec( (uchar const *)info->val, &num );
52 0 : long snum = fd_long_zz_dec( num );
53 0 : if( snum < 0L ) {
54 0 : FD_LOG_WARNING(( "`%s` cannot be negative", path ));
55 0 : return 0;
56 0 : }
57 0 : num = (ulong)snum;
58 0 : break;
59 0 : case FD_POD_VAL_TYPE_ULONG:
60 0 : fd_ulong_svw_dec( (uchar const *)info->val, &num );
61 0 : break;
62 0 : default:
63 0 : FD_LOG_WARNING(( "invalid value for `%s`", path ));
64 0 : return 0;
65 0 : }
66 :
67 0 : *out = num;
68 0 : return 1;
69 0 : }
70 :
71 : static inline int
72 : fdctl_cfg_get_uint( uint * out,
73 : ulong out_sz FD_PARAM_UNUSED,
74 : fd_pod_info_t const * info,
75 0 : char const * path ) {
76 0 : ulong num;
77 0 : if( FD_UNLIKELY( !fdctl_cfg_get_ulong( &num, sizeof(num), info, path ) ) ) return 0;
78 0 : if( num > UINT_MAX ) {
79 0 : FD_LOG_WARNING(( "`%s` is out of bounds (%lx)", path, num ));
80 0 : return 0;
81 0 : }
82 0 : *out = (uint)num;
83 0 : return 1;
84 0 : }
85 :
86 : static inline int
87 : fdctl_cfg_get_ushort( ushort * out,
88 : ulong out_sz FD_PARAM_UNUSED,
89 : fd_pod_info_t const * info,
90 0 : char const * path ) {
91 0 : ulong num;
92 0 : if( FD_UNLIKELY( !fdctl_cfg_get_ulong( &num, sizeof(num), info, path ) ) ) return 0;
93 0 : if( num > USHORT_MAX ) {
94 0 : FD_LOG_WARNING(( "`%s` is out of bounds (%lx)", path, num ));
95 0 : return 0;
96 0 : }
97 0 : *out = (ushort)num;
98 0 : return 1;
99 0 : }
100 :
101 : static inline int
102 : fdctl_cfg_get_bool( int * out,
103 : ulong out_sz FD_PARAM_UNUSED,
104 : fd_pod_info_t const * info,
105 0 : char const * path ) {
106 0 : if( FD_UNLIKELY( info->val_type != FD_POD_VAL_TYPE_INT ) ) {
107 0 : FD_LOG_WARNING(( "invalid value for `%s`", path ));
108 0 : return 0;
109 0 : }
110 0 : ulong u; fd_ulong_svw_dec( (uchar const *)info->val, &u );
111 0 : *out = fd_int_zz_dec( (uint)u );
112 0 : return 1;
113 0 : }
114 :
115 : /* Handles true, false, "true", "false" and "auto" */
116 : static inline int
117 : fdctl_cfg_get_boolau( int * out,
118 : ulong out_sz FD_PARAM_UNUSED,
119 : fd_pod_info_t const * info,
120 0 : char const * path ) {
121 0 : if( info->val_type==FD_POD_VAL_TYPE_CSTR ) {
122 0 : char const * info_val = (char const *)info->val;
123 0 : if( !strcmp( info_val, "auto" ) ) {
124 0 : *out = FD_BOOLAU_AUTO;
125 0 : return 1;
126 0 : } else if( !strcmp( info_val, "true" ) ) {
127 0 : *out = FD_BOOLAU_TRUE;
128 0 : return 1;
129 0 : } else if( !strcmp( info_val, "false" ) ) {
130 0 : *out = FD_BOOLAU_FALSE;
131 0 : return 1;
132 0 : }
133 0 : FD_LOG_WARNING(( "invalid value of `%s` entered for `%s`, must be true, false or auto. ",
134 0 : info_val, path ));
135 0 : return 0;
136 0 : }
137 0 : return fdctl_cfg_get_bool( out, out_sz, info, path );
138 0 : }
139 :
140 : static inline int
141 : fdctl_cfg_get_float( float * out,
142 : ulong out_sz FD_PARAM_UNUSED,
143 : fd_pod_info_t const * info,
144 0 : char const * path ) {
145 0 :
146 0 : ulong unum;
147 0 : float num;
148 0 : switch( info->val_type ) {
149 0 : case FD_POD_VAL_TYPE_LONG:
150 0 : fd_ulong_svw_dec( (uchar const *)info->val, &unum );
151 0 : long snum = fd_long_zz_dec( unum );
152 0 : if( snum < 0L ) {
153 0 : FD_LOG_WARNING(( "`%s` cannot be negative", path ));
154 0 : return 0;
155 0 : }
156 0 : num = (float)snum;
157 0 : break;
158 0 : case FD_POD_VAL_TYPE_ULONG:
159 0 : fd_ulong_svw_dec( (uchar const *)info->val, &unum );
160 0 : num = (float)unum;
161 0 : break;
162 0 : case FD_POD_VAL_TYPE_FLOAT:
163 0 : num = FD_LOAD( float, info->val );
164 0 : break;
165 0 : default:
166 0 : FD_LOG_WARNING(( "invalid value for `%s`", path ));
167 0 : return 0;
168 0 : }
169 0 :
170 0 : *out = num;
171 0 : return 1;
172 0 : }
173 :
174 : FD_PROTOTYPES_END
175 :
176 : #endif /* HEADER_fd_src_app_platform_fd_config_extract_h */
|