HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
command_line.hpp
1// Copyright Take Vos 2021.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#include "coroutine"
6#include "os_detect.hpp"
7
8#pragma once
9
10namespace tt {
11
13 char32_t option;
14 std::option<std::string> argument;
15};
16
18 std::string option;
19 std::option<std::string> argument;
20};
21
23 std::string executable;
24};
25
27 std::string argument;
28};
29
30using cmdline_option = std::variant<cmline_executable, cmdline_short_option, cmdline_long_option, cmdline_argument>;
31
59template<typename It>
60generator<cmdln_option> command_line_parser(It first, It last, std::string_view options_with_arguments)
61{
62 ttlet options_with_arguments_ = tt::to_u32string(options_with_arguments);
63 auto it = first;
64
65 if (it != last) {
66 co_yield cmdln_option::executable{*it};
67 ++it;
68 }
69
70 char32_t short_option_name = 0;
71 for (; it != last; ++it) {
72 if (short_option_name) {
73 // Add the argument to the option.
74 co_yield cmdln_short_option{short_option_name, *it};
75 short_option_name = 0;
76
77 } else if (*it == "--") {
78 break;
79
80 } else if (it->starts_with("--")) {
81 // Long-option
82 ttlet eq_index = it->find('=');
83 if (eq_index == std::string::npos) {
84 // Long-option without argument
85 co_yield cmdln_long_option{it->substr(2), {}};
86
87 } else {
88 // Long-option with argument in same token.
89 tt_axiom(eq_index >= 2);
90 ttlet name_length = eq_index - 2;
91 co_yield cmdln_long_option(it->substr(2, name_length), it->substr(eq_index + 1));
92 }
93
94 } else if (it.front() == '-' || it.front() == '+') {
95 // List of short-options.
96 // Short options are processed as UTF-32 units.
97 ttlet token = to_u32string(*it);
98 ttlet first_c = std::next(std::begin(token));
99 ttlet last_c = std::end(token);
100 negative = it.front() == '+';
101
102 for (auto jt = first_c; jt != last_c; ++jt) {
103 ttlet c = *jt;
104 auto name = tt::to_string(std::u32string(1, c));
105
106 if (options_with_arguments_.find(c) == std::u32string::npos) {
107 // Option without argument
108 co_yield cmdln_short_option(c, {});
109
110 } else if (std::next(jt) == last) {
111 // Option with the argument in the next token.
112 short_option_name = c;
113
114 } else {
115 // Option with argument, where the argument is inside this token
116 auto argument = tt::to_string(std::u32string(std::next(jt), last_c));
117 co_yield cmdln_short_option(c, std::move(argument));
118 break;
119 }
120 }
121
122 } else {
123 // Anything not looking like an option is a non-option
124 co_yield cmdln_non_option{*it};
125 }
126 }
127
128 // All tokens after double hyphen '--' are non-options.
129 for (;it != last; ++it) {
130 co_yield cmdln_non_option{*it};
131 }
132
133 if (short_option_name) {
134 throw parse_error("Missing argument for option -{}", short_option_name);
135 }
136}
137
139public:
140 char32_t short_option;
141 std::string long_option;
142 std::string argument_name;
143 std::string description;
144 tt::notifier<void(std::string_view argument)> notifier;
145
165 constexpr command_line_option(std::string_view option_help) {
166 auto it = std::begin(option_help);
167 ttlet last = std::end(option_help);
168
169
170
171
172 }
173
174 static char32_t parse_short_option(std::string_view::iterator &it, std::string_view::iterator last)
175 {
176 if (it == last || *it != '-') {
177 throw parse_error("Expecting '-'");
178 }
179
180 ++it;
181
182 if (it == last) {
183 throw parse_error("Missing character after '-'");
184 }
185 if (*it == '-') {
186 return 0;
187 }
188 }
189};
190
194public:
195#if TT_OPERATING_SYSTEM == TT_OS_WINDOWS
196 void parse();
197#else
198 void parse(int argc, char **argv);
199#endif
200
201 template<typename... Args>
202 command_line_option &add_option(Args &&... args) noexcept {
203 return _options.emplace(std::forward<Args>(args)...);
204 }
205
206private:
208};
209
210
211}
212
Definition command_line.hpp:12
Definition command_line.hpp:17
Definition command_line.hpp:22
Definition command_line.hpp:26
Definition command_line.hpp:138
constexpr command_line_option(std::string_view option_help)
Syntax:
Definition command_line.hpp:165
Command line parser.
Definition command_line.hpp:193
A return value for a generator-function.
Definition coroutine.hpp:24
Exception thrown during parsing on an error.
Definition exception.hpp:21
Definition notifier.hpp:17
T begin(T... args)
T end(T... args)
T move(T... args)
T next(T... args)