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 153 : char const * path ) {
24 153 : if( FD_UNLIKELY( info->val_type != FD_POD_VAL_TYPE_CSTR ) ) {
25 0 : FD_LOG_WARNING(( "invalid value for `%s`", path ));
26 0 : return 0;
27 0 : }
28 153 : char const * str = info->val;
29 153 : ulong sz = strlen( str ) + 1;
30 153 : if( FD_UNLIKELY( sz > out_sz ) ) {
31 0 : FD_LOG_WARNING(( "`%s`: too long (max %ld)", path, (long)out_sz-1L ));
32 0 : return 0;
33 0 : }
34 153 : fd_memcpy( out, str, sz );
35 153 : return 1;
36 153 : }
37 :
38 : #define fdctl_cfg_get_cstr( out, out_sz, info, path ) \
39 6 : 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 180 : char const * path ) {
46 :
47 180 : ulong num;
48 180 : switch( info->val_type ) {
49 180 : case FD_POD_VAL_TYPE_LONG:
50 180 : fd_ulong_svw_dec( (uchar const *)info->val, &num );
51 180 : long snum = fd_long_zz_dec( num );
52 180 : if( snum < 0L ) {
53 0 : FD_LOG_WARNING(( "`%s` cannot be negative", path ));
54 0 : return 0;
55 0 : }
56 180 : num = (ulong)snum;
57 180 : 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 180 : }
65 :
66 180 : *out = num;
67 180 : return 1;
68 180 : }
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 108 : char const * path ) {
75 108 : ulong num;
76 108 : if( FD_UNLIKELY( !fdctl_cfg_get_ulong( &num, sizeof(num), info, path ) ) ) return 0;
77 108 : if( num > UINT_MAX ) {
78 0 : FD_LOG_WARNING(( "`%s` is out of bounds (%lx)", path, num ));
79 0 : return 0;
80 0 : }
81 108 : *out = (uint)num;
82 108 : return 1;
83 108 : }
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 24 : char const * path ) {
90 24 : ulong num;
91 24 : if( FD_UNLIKELY( !fdctl_cfg_get_ulong( &num, sizeof(num), info, path ) ) ) return 0;
92 24 : if( num > USHORT_MAX ) {
93 0 : FD_LOG_WARNING(( "`%s` is out of bounds (%lx)", path, num ));
94 0 : return 0;
95 0 : }
96 24 : *out = (ushort)num;
97 24 : return 1;
98 24 : }
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 108 : char const * path ) {
105 108 : 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 108 : ulong u; fd_ulong_svw_dec( (uchar const *)info->val, &u );
110 108 : *out = fd_int_zz_dec( (uint)u );
111 108 : return 1;
112 108 : }
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 15 : char const * path ) {
120 15 : if( info->val_type==FD_POD_VAL_TYPE_CSTR ) {
121 15 : char const * info_val = (char const *)info->val;
122 15 : if( !strcmp( info_val, "auto" ) ) {
123 6 : *out = 2;
124 6 : return 1;
125 9 : } else if( !strcmp( info_val, "true" ) ) {
126 0 : *out = 1;
127 0 : return 1;
128 9 : } else if( !strcmp( info_val, "false" ) ) {
129 6 : *out = 0;
130 6 : return 1;
131 6 : }
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 15 : }
136 0 : return fdctl_cfg_get_bool( out, out_sz, info, path );
137 15 : }
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 */
|