1212
1313#include < map>
1414#include < string>
15+ #include < sstream>
1516#include < vector>
16- #include " src/common/liboptmgr/optmgr_impl.hpp"
1717
1818namespace Flux {
1919namespace opts_manager {
@@ -97,14 +97,14 @@ class optmgr_composer_t {
9797 * iteration order on the option set.
9898 */
9999template <class T >
100- struct optmgr_kv_t : public detail :: optmgr_kv_impl_t <T> {
100+ struct optmgr_kv_t {
101101
102102 /* ! Getter
103103 *
104104 * \return Option set object of type T of "this" object.
105105 */
106106 const T &get_opt () const {
107- return detail:: optmgr_kv_impl_t <T>:: get_opt () ;
107+ return m_opt ;
108108 }
109109
110110 /* ! Put
@@ -115,7 +115,19 @@ struct optmgr_kv_t : public detail::optmgr_kv_impl_t<T> {
115115 * \return 0 on success; -1 on error.
116116 */
117117 int put (const std::string &k, const std::string &v) {
118- return detail::optmgr_kv_impl_t <T>::put (k, v);
118+ int rc = 0 ;
119+ try {
120+ auto ret = m_kv.insert (std::pair<std::string, std::string> (k, v));
121+ if (!ret.second ) {
122+ errno = EEXIST;
123+ rc = -1 ;
124+ }
125+ }
126+ catch (std::bad_alloc &) {
127+ errno = ENOMEM;
128+ rc = -1 ;
129+ }
130+ return rc;
119131 }
120132
121133 /* ! Put
@@ -125,7 +137,12 @@ struct optmgr_kv_t : public detail::optmgr_kv_impl_t<T> {
125137 * \return 0 on success; -1 on error.
126138 */
127139 int put (const std::string &kv) {
128- return detail::optmgr_kv_impl_t <T>::put (kv);
140+ size_t found = std::string::npos;
141+ if ( (found = kv.find_first_of (" =" )) == std::string::npos) {
142+ errno = EPROTO;
143+ return -1 ;
144+ }
145+ return put (kv.substr (0 , found), kv.substr (found + 1 ));
129146 }
130147
131148 /* ! Get
@@ -136,7 +153,19 @@ struct optmgr_kv_t : public detail::optmgr_kv_impl_t<T> {
136153 * \return 0 on success; -1 on error.
137154 */
138155 int get (const std::string &k, std::string &v) const {
139- return detail::optmgr_kv_impl_t <T>::get (k, v);
156+ int rc = 0 ;
157+ try {
158+ v = m_kv.at (k);
159+ }
160+ catch (std::bad_alloc &) {
161+ errno = ENOMEM;
162+ rc = -1 ;
163+ }
164+ catch (std::out_of_range &) {
165+ errno = ENOENT;
166+ rc = -1 ;
167+ }
168+ return rc;
140169 }
141170
142171 /* ! Parse key=value option pairs and update the state of
@@ -147,15 +176,26 @@ struct optmgr_kv_t : public detail::optmgr_kv_impl_t<T> {
147176 * \return 0 on success; -1 on error.
148177 */
149178 int parse (std::string &info) {
150- return detail::optmgr_kv_impl_t <T>::parse (info);
179+ int rc = 0 ;
180+ for (const auto &kv : m_kv) {
181+ // If T doesn't have parse method, this produces an compiler error
182+ if ( (rc = m_opt.parse (kv.first , kv.second , info)) < 0 ) {
183+ return rc;
184+ }
185+ }
186+ return rc;
151187 }
188+
189+ private:
190+ T m_opt;
191+ std::map<std::string, std::string, T> m_kv;
152192};
153193
154194
155195/* ! Parsing utilities.
156196 *
157197 */
158- struct optmgr_parse_t : public detail :: optmgr_parse_impl_t {
198+ struct optmgr_parse_t {
159199
160200 /* ! Parse a string that contains key and value delimited with token.
161201 * The parsed key and value are passed through k and v respectively.
@@ -170,7 +210,18 @@ struct optmgr_parse_t : public detail::optmgr_parse_impl_t {
170210 */
171211 int parse_single (const std::string &str, const std::string &token,
172212 std::string &k, std::string &v) {
173- return detail::optmgr_parse_impl_t::parse_single (str, token, k, v);
213+ size_t found;
214+ if (str == " " || token == " " ) {
215+ errno = EINVAL;
216+ return -1 ;
217+ }
218+ if ( (found = str.find_first_of (token)) == std::string::npos) {
219+ errno = EPROTO;
220+ return -1 ;
221+ }
222+ k = str.substr (0 , found);
223+ v = str.substr (found + 1 );
224+ return 0 ;
174225 }
175226
176227 /* ! Parse multi_value string: each value is delimited with the
@@ -188,8 +239,19 @@ struct optmgr_parse_t : public detail::optmgr_parse_impl_t {
188239 */
189240 int parse_multi (const std::string multi_value, const char delim,
190241 std::vector<std::string> &entries) {
191- return detail::optmgr_parse_impl_t::parse_multi (multi_value,
192- delim, entries);
242+ int rc = 0 ;
243+ try {
244+ std::stringstream ss;
245+ std::string entry;
246+ ss << multi_value;
247+ while (getline (ss, entry, delim))
248+ entries.push_back (entry);
249+ }
250+ catch (std::bad_alloc &) {
251+ errno = ENOMEM;
252+ rc = -1 ;
253+ }
254+ return rc;
193255 }
194256
195257 /* ! Parse the m_opts string that contains multiple options delimited
@@ -209,8 +271,31 @@ struct optmgr_parse_t : public detail::optmgr_parse_impl_t {
209271 int parse_multi_options (const std::string &m_opts, const char odelim,
210272 const char kdelim, std::map<std::string,
211273 std::string> &opt_mp) {
212- return detail::optmgr_parse_impl_t::parse_multi_options (m_opts, odelim,
213- kdelim, opt_mp);
274+ int rc = 0 ;
275+ try {
276+ std::vector<std::string> entries;
277+ if ( (rc = parse_multi (m_opts, odelim, entries)) < 0 )
278+ goto done;
279+ for (const auto &entry : entries) {
280+ std::string n = " " ;
281+ std::string v = " " ;
282+ if ( (rc = parse_single (entry, std::string (1 , kdelim), n, v)) < 0 )
283+ goto done;
284+ auto ret = opt_mp.insert (std::pair<std::string,
285+ std::string> (n, v));
286+ if (!ret.second ) {
287+ errno = EEXIST;
288+ rc = -1 ;
289+ goto done;
290+ }
291+ }
292+ }
293+ catch (std::bad_alloc &) {
294+ errno = ENOMEM;
295+ rc = -1 ;
296+ }
297+ done:
298+ return rc;
214299 }
215300};
216301
0 commit comments