1
+ /*
2
+ * Copyright © Canonical Ltd.
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify it
5
+ * under the terms of the GNU Lesser General Public License version 2 or 3,
6
+ * as published by the Free Software Foundation.
7
+ *
8
+ * This program is distributed in the hope that it will be useful,
9
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ * GNU Lesser General Public License for more details.
12
+ *
13
+ * You should have received a copy of the GNU Lesser General Public License
14
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+ */
16
+
17
+ #include " options_parsing_helpers.h"
18
+ #include < stdexcept>
19
+ #include < boost/throw_exception.hpp>
20
+
21
+ namespace mgc = mir::graphics::common;
22
+ namespace geom = mir::geometry;
23
+
24
+ namespace
25
+ {
26
+ auto parse_scale (std::string const & str) -> float
27
+ {
28
+ try
29
+ {
30
+ size_t num_end = 0 ;
31
+ float const value = std::stof (str, &num_end);
32
+ if (num_end != str.size ())
33
+ BOOST_THROW_EXCEPTION (std::runtime_error (" Scale \" " + str + " \" is not a valid float" ));
34
+ if (value <= 0.000001 )
35
+ BOOST_THROW_EXCEPTION (std::runtime_error (" Scale must be greater than zero" ));
36
+ return value;
37
+ }
38
+ catch (std::invalid_argument const &)
39
+ {
40
+ BOOST_THROW_EXCEPTION (std::runtime_error (" Scale \" " + str + " \" is not a valid float" ));
41
+ }
42
+ catch (std::out_of_range const &)
43
+ {
44
+ BOOST_THROW_EXCEPTION (std::runtime_error (" Scale \" " + str + " \" is out of range" ));
45
+ }
46
+ }
47
+
48
+ auto parse_size_dimension (std::string const & str) -> int
49
+ {
50
+ try
51
+ {
52
+ size_t num_end = 0 ;
53
+ int const value = std::stoi (str, &num_end);
54
+ if (num_end != str.size ())
55
+ BOOST_THROW_EXCEPTION (std::runtime_error (" Output dimension \" " + str + " \" is not a valid number" ));
56
+ if (value <= 0 )
57
+ BOOST_THROW_EXCEPTION (std::runtime_error (" Output dimensions must be greater than zero" ));
58
+ return value;
59
+ }
60
+ catch (std::invalid_argument const &)
61
+ {
62
+ BOOST_THROW_EXCEPTION (std::runtime_error (" Output dimension \" " + str + " \" is not a valid number" ));
63
+ }
64
+ catch (std::out_of_range const &)
65
+ {
66
+ BOOST_THROW_EXCEPTION (std::runtime_error (" Output dimension \" " + str + " \" is out of range" ));
67
+ }
68
+ }
69
+ }
70
+
71
+
72
+ auto mgc::parse_size (std::string const & str) -> geom::Size
73
+ {
74
+ auto const x = str.find (' x' ); // "x" between width and height
75
+ if (x == std::string::npos || x <= 0 || x >= str.size () - 1 )
76
+ BOOST_THROW_EXCEPTION (std::runtime_error (" Output size \" " + str + " \" does not have two dimensions" ));
77
+ return geom::Size {
78
+ parse_size_dimension (str.substr (0 , x)),
79
+ parse_size_dimension (str.substr (x + 1 ))};
80
+ }
81
+
82
+ auto mgc::parse_size_with_scale (std::string const & str) -> std::tuple<mir::geometry::Size, float>
83
+ {
84
+ auto const x = str.find (' x' ); // "x" between width and height
85
+ if (x == std::string::npos || x <= 0 || x >= str.size () - 1 )
86
+ BOOST_THROW_EXCEPTION (std::runtime_error (" Output size \" " + str + " \" does not have two dimensions" ));
87
+ auto const scale_start = str.find (' ^' ); // start of output scale
88
+ float scale = 1 .0f ;
89
+ if (scale_start != std::string::npos)
90
+ {
91
+ if (scale_start >= str.size () - 1 )
92
+ BOOST_THROW_EXCEPTION (std::runtime_error (" In \" " + str + " \" , '^' is not followed by a scale" ));
93
+ scale = parse_scale (str.substr (scale_start + 1 , std::string::npos));
94
+ }
95
+ return {geom::Size {
96
+ parse_size_dimension (str.substr (0 , x)),
97
+ parse_size_dimension (str.substr (x + 1 , scale_start - x - 1 ))},
98
+ scale};
99
+ }
0 commit comments