]>
Commit | Line | Data |
---|---|---|
1e95832b GS |
1 | #include <config.h> |
2 | ||
3b161085 | 3 | const DataType *ConfigKey::data_type() const |
c23c8659 | 4 | { |
21d1bec6 | 5 | const struct sr_key_info *info = sr_key_info_get(SR_KEY_CONFIG, id()); |
c23c8659 ML |
6 | if (!info) |
7 | throw Error(SR_ERR_NA); | |
8 | return DataType::get(info->datatype); | |
9 | } | |
10 | ||
6c6dd732 | 11 | std::string ConfigKey::identifier() const |
c23c8659 | 12 | { |
21d1bec6 | 13 | const struct sr_key_info *info = sr_key_info_get(SR_KEY_CONFIG, id()); |
c23c8659 ML |
14 | if (!info) |
15 | throw Error(SR_ERR_NA); | |
16 | return valid_string(info->id); | |
17 | } | |
18 | ||
6c6dd732 | 19 | std::string ConfigKey::description() const |
c23c8659 | 20 | { |
21d1bec6 | 21 | const struct sr_key_info *info = sr_key_info_get(SR_KEY_CONFIG, id()); |
c23c8659 ML |
22 | if (!info) |
23 | throw Error(SR_ERR_NA); | |
24 | return valid_string(info->name); | |
25 | } | |
26 | ||
6c6dd732 | 27 | const ConfigKey *ConfigKey::get_by_identifier(std::string identifier) |
c23c8659 | 28 | { |
2fb60e23 | 29 | const struct sr_key_info *info = sr_key_info_name_get(SR_KEY_CONFIG, identifier.c_str()); |
c23c8659 ML |
30 | if (!info) |
31 | throw Error(SR_ERR_ARG); | |
32 | return get(info->key); | |
33 | } | |
34 | ||
d92de05a MC |
35 | #ifndef HAVE_STOI_STOD |
36 | ||
37 | /* Fallback implementation of stoi and stod */ | |
38 | ||
39 | #include <cstdlib> | |
40 | #include <cerrno> | |
41 | #include <stdexcept> | |
42 | #include <limits> | |
43 | ||
44 | static inline int stoi( const std::string& str ) | |
45 | { | |
46 | char *endptr; | |
47 | errno = 0; | |
48 | const long ret = std::strtol(str.c_str(), &endptr, 10); | |
49 | if (endptr == str.c_str()) | |
50 | throw std::invalid_argument("stoi"); | |
51 | else if (errno == ERANGE || | |
52 | ret < std::numeric_limits<int>::min() || | |
53 | ret > std::numeric_limits<int>::max()) | |
54 | throw std::out_of_range("stoi"); | |
55 | else | |
56 | return ret; | |
57 | } | |
58 | ||
59 | static inline double stod( const std::string& str ) | |
60 | { | |
61 | char *endptr; | |
62 | errno = 0; | |
63 | const double ret = std::strtod(str.c_str(), &endptr); | |
64 | if (endptr == str.c_str()) | |
65 | throw std::invalid_argument("stod"); | |
66 | else if (errno == ERANGE) | |
67 | throw std::out_of_range("stod"); | |
68 | else | |
69 | return ret; | |
70 | } | |
71 | #endif | |
72 | ||
f806de18 GS |
73 | #ifndef HAVE_STOUL |
74 | ||
75 | /* Fallback implementation of stoul. */ | |
76 | ||
77 | #include <cerrno> | |
78 | #include <cstdlib> | |
79 | #include <limits> | |
80 | #include <stdexcept> | |
81 | ||
82 | static inline unsigned long stoul(const std::string &str) | |
83 | { | |
84 | char *endptr; | |
85 | unsigned long ret; | |
86 | errno = 0; | |
87 | ret = std::strtoul(str.c_str(), &endptr, 10); | |
88 | if (endptr == str.c_str()) | |
89 | throw std::invalid_argument("stoul"); | |
90 | /* | |
91 | * TODO Convert to a larger/wider intermediate data type? | |
92 | * Because after conversion into the very target type, the | |
93 | * range check is assumed to be ineffective. | |
94 | */ | |
95 | if (errno == ERANGE || | |
96 | ret < std::numeric_limits<unsigned long>::min() || | |
97 | ret > std::numeric_limits<unsigned long>::max()) | |
98 | throw std::out_of_range("stoul"); | |
99 | return ret; | |
100 | } | |
101 | #endif | |
102 | ||
0db1b189 MH |
103 | // Conversion from text to uint32_t, including a range check. |
104 | // This is sigrok specific, _not_ part of any C++ standard library. | |
105 | static uint32_t stou32(const std::string &str) | |
106 | { | |
107 | unsigned long ret; | |
108 | errno = 0; | |
109 | ret = stoul(str); | |
110 | if (errno == ERANGE) | |
111 | throw std::out_of_range("stou32"); | |
112 | if (ret > std::numeric_limits<uint32_t>::max()) | |
113 | throw std::out_of_range("stou32"); | |
114 | return ret; | |
115 | } | |
116 | ||
6c6dd732 | 117 | Glib::VariantBase ConfigKey::parse_string(std::string value, enum sr_datatype dt) |
c23c8659 ML |
118 | { |
119 | GVariant *variant; | |
120 | uint64_t p, q; | |
121 | ||
61a6d983 | 122 | switch (dt) |
c23c8659 ML |
123 | { |
124 | case SR_T_UINT64: | |
125 | check(sr_parse_sizestring(value.c_str(), &p)); | |
126 | variant = g_variant_new_uint64(p); | |
127 | break; | |
128 | case SR_T_STRING: | |
129 | variant = g_variant_new_string(value.c_str()); | |
130 | break; | |
131 | case SR_T_BOOL: | |
132 | variant = g_variant_new_boolean(sr_parse_boolstring(value.c_str())); | |
133 | break; | |
134 | case SR_T_FLOAT: | |
4aa9a1e5 ML |
135 | try { |
136 | variant = g_variant_new_double(stod(value)); | |
0875f11d | 137 | } catch (invalid_argument&) { |
4aa9a1e5 ML |
138 | throw Error(SR_ERR_ARG); |
139 | } | |
c23c8659 ML |
140 | break; |
141 | case SR_T_RATIONAL_PERIOD: | |
142 | check(sr_parse_period(value.c_str(), &p, &q)); | |
143 | variant = g_variant_new("(tt)", p, q); | |
144 | break; | |
145 | case SR_T_RATIONAL_VOLT: | |
146 | check(sr_parse_voltage(value.c_str(), &p, &q)); | |
147 | variant = g_variant_new("(tt)", p, q); | |
148 | break; | |
149 | case SR_T_INT32: | |
4aa9a1e5 ML |
150 | try { |
151 | variant = g_variant_new_int32(stoi(value)); | |
0875f11d | 152 | } catch (invalid_argument&) { |
4aa9a1e5 ML |
153 | throw Error(SR_ERR_ARG); |
154 | } | |
c23c8659 | 155 | break; |
0db1b189 MH |
156 | case SR_T_UINT32: |
157 | try { | |
158 | variant = g_variant_new_uint32(stou32(value)); | |
159 | } catch (invalid_argument&) { | |
160 | throw Error(SR_ERR_ARG); | |
161 | } | |
162 | break; | |
c23c8659 ML |
163 | default: |
164 | throw Error(SR_ERR_BUG); | |
165 | } | |
166 | ||
7009a392 | 167 | return Glib::VariantBase(variant, false); |
c23c8659 ML |
168 | } |
169 | ||
6c6dd732 | 170 | Glib::VariantBase ConfigKey::parse_string(std::string value) const |
61a6d983 GS |
171 | { |
172 | enum sr_datatype dt = (enum sr_datatype)(data_type()->id()); | |
173 | return parse_string(value, dt); | |
174 | } |