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