|
1 /** |
|
2 * ShaderShark |
|
3 * Copyright © 2023 František Kučera (Frantovo.cz, GlobalCode.info) |
|
4 * |
|
5 * This program is free software: you can redistribute it and/or modify |
|
6 * it under the terms of the GNU General Public License as published by |
|
7 * the Free Software Foundation, version 3 of the License. |
|
8 * |
|
9 * This program is distributed in the hope that it will be useful, |
|
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 * GNU General Public License for more details. |
|
13 * |
|
14 * You should have received a copy of the GNU General Public License |
|
15 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
16 */ |
|
17 |
|
18 #pragma once |
|
19 |
|
20 #include <vector> |
|
21 #include <string> |
|
22 |
|
23 #include "Configuration.h" |
|
24 |
|
25 class CLIParser { |
|
26 private: |
|
27 |
|
28 static const std::string OPTION_TEXTURE; |
|
29 static const std::string OPTION_BACKGROUND_COLOR; |
|
30 static const std::string OPTION_ROOT_WINDOW; |
|
31 |
|
32 const std::string |
|
33 readNext(const std::vector<std::string>& arguments, int& i) { |
|
34 if (i < arguments.size()) return arguments[i++]; |
|
35 else throw std::logic_error("Missing CLI argument" |
|
36 + (i > 0 ? (" after " + arguments[i - 1]) : "")); |
|
37 } |
|
38 |
|
39 bool parseBoolean(const std::string& value) { |
|
40 if (value == "true") return true; |
|
41 else if (value == "false") return false; |
|
42 else throw std::logic_error("Unable to parse boolean value: " |
|
43 + value + " (expecting true or false)"); |
|
44 } |
|
45 |
|
46 unsigned long |
|
47 parseHexColor(const std::string& hex) { |
|
48 int r, g, b; |
|
49 int count = sscanf(hex.c_str(), "%02x%02x%02x", &r, &g, &b); |
|
50 if (count == 3) { |
|
51 unsigned long lr, lg, lb; |
|
52 lr = r; |
|
53 lg = g; |
|
54 lb = b; |
|
55 return (lr << 16 | lg << 8 | lb); |
|
56 } else { |
|
57 throw std::logic_error("Invalid hex color string"); |
|
58 } |
|
59 } |
|
60 |
|
61 public: |
|
62 |
|
63 const Configuration parse(const std::vector<std::string>& arguments) { |
|
64 Configuration c; |
|
65 |
|
66 for (int i = 0; i < arguments.size();) { |
|
67 const std::string& option = readNext(arguments, i); |
|
68 |
|
69 if (option == OPTION_TEXTURE) { |
|
70 Configuration::Texture tex; |
|
71 tex.fileName = readNext(arguments, i); |
|
72 c.textures.push_back(tex); |
|
73 } else if (option == OPTION_BACKGROUND_COLOR) { |
|
74 c.backgroundColor = parseHexColor(readNext(arguments, i)); |
|
75 } else if (option == OPTION_ROOT_WINDOW) { |
|
76 c.rootWindow = std::stoul(readNext(arguments, i)); |
|
77 } else throw std::logic_error("Unsupported CLI option: " + option); |
|
78 } |
|
79 |
|
80 return c; |
|
81 } |
|
82 }; |
|
83 |
|
84 const std::string CLIParser::OPTION_TEXTURE = "--texture"; |
|
85 const std::string CLIParser::OPTION_BACKGROUND_COLOR = "--background-color"; |
|
86 const std::string CLIParser::OPTION_ROOT_WINDOW = "--root-window"; |