Sequoia
Loading...
Searching...
No Matches
CommandLineArguments.hpp
Go to the documentation of this file.
1
2// Copyright Oliver J. Rosten 2020. //
3// Distributed under the GNU GENERAL PUBLIC LICENSE, Version 3.0. //
4// (See accompanying file LICENSE.md or copy at //
5// https://www.gnu.org/licenses/gpl-3.0.en.html) //
7
8#pragma once
9
20
23
24#include <vector>
25#include <string>
26#include <functional>
27#include <stdexcept>
28
29namespace sequoia::parsing::commandline
30{
33 {
34 public:
35 proper_string(std::string s) : m_String{std::move(s)}
36 {
37 if(m_String.empty())
38 throw std::logic_error{"Empty string detected"};
39 }
40
41 proper_string(const char* c) : proper_string{std::string{c}}
42 {}
43
44 [[nodiscard]]
45 operator const std::string& () const noexcept
46 {
47 return m_String;
48 }
49
50 [[nodiscard]]
51 operator std::string_view() const noexcept
52 {
53 return m_String;
54 }
55
56 [[nodiscard]]
57 friend bool operator==(const proper_string&, const proper_string&) noexcept = default;
58 private:
59 std::string m_String;
60 };
61
62 using param_list = std::vector<proper_string>;
63 using arg_list = std::vector<std::string>;
64
65 using executor = std::function<void (const arg_list&)>;
66
79 struct option
80 {
81 proper_string name;
82 param_list aliases{},
83 parameters{};
84 executor early{},
85 late{};
86 };
87
99 struct operation
100 {
101 executor early{}, late{};
102 arg_list arguments{};
103 };
104
106 using options_forest = std::vector<options_tree>;
108
111 using operations_forest = std::vector<operations_tree>;
112
118 struct outcome
119 {
120 std::string zeroth_arg;
121 operations_forest operations;
122 std::string help{};
123 };
124
125 [[nodiscard]]
126 std::string error(std::string_view message, std::string_view indent=" ");
127
128 [[nodiscard]]
129 std::string error(std::initializer_list<std::string_view> messages, std::string_view indent = " ");
130
131 [[nodiscard]]
132 std::string warning(std::string_view message, std::string_view indent=" ");
133
134 [[nodiscard]]
135 std::string warning(std::initializer_list<std::string_view> messages, std::string_view indent = " ");
136
137 [[nodiscard]]
138 std::string pluralize(std::size_t n, std::string_view noun, std::string_view prefix=" ");
139
140 [[nodiscard]]
141 outcome parse(int argc, char** argv, const options_forest& options);
142
143
144 template<std::invocable<std::string> Fn>
145 [[nodiscard]]
146 std::string parse_invoke_depth_first(int argc, char** argv, const options_forest options, Fn zerothArgProcessor)
147 {
148 auto[zerothArg, operations, help]{parse(argc, argv, options)};
149
150 if(help.empty())
151 {
152 zerothArgProcessor(zerothArg);
153
154 using namespace maths;
155 for(const auto& operTree : operations)
156 {
157 traverse(depth_first,
158 operTree,
159 ignore_disconnected_t{},
160 [&operTree](const auto node) {
161 const operation& oper{operTree.cbegin_node_weights()[node]};
162 if(oper.early) oper.early(oper.arguments);
163 },
164 [&operTree](const auto node) {
165 const operation& oper{operTree.cbegin_node_weights()[node]};
166 if(oper.late) oper.late(oper.arguments);
167 });
168 }
169 }
170
171 return help;
172 }
173
176 {
177 public:
178
179 argument_parser(int argc, char** argv, const options_forest& options);
180
181 [[nodiscard]]
182 outcome get() const
183 {
184 return {m_ZerothArg, m_Operations, m_Help};
185 }
186 private:
187 enum class top_level { yes, no };
188
189 struct operation_data
190 {
191 operations_sub_tree oper_tree{};
192 std::size_t saturated_args{};
193 };
194
195 operations_forest m_Operations{};
196 int m_Index{1}, m_ArgCount{};
197 char** m_Argv{};
198 std::string m_ZerothArg{}, m_Help{};
199
200 template<std::input_iterator Iter>
201 void parse(std::ranges::subrange<Iter> options, const operation_data& previousOperationData, top_level topLevel);
202
203 template<std::input_iterator Iter>
204 [[nodiscard]]
205 bool process_concatenated_aliases(std::ranges::subrange<Iter> options, std::string_view arg, operation_data currentOperationData, top_level topLevel);
206
207 auto process_option(option_tree currentOptionTree, operation_data currentOperationData, top_level topLevel)->operation_data;
208
209 template<std::input_iterator Iter>
210 [[nodiscard]]
211 static std::string generate_help(std::ranges::subrange<Iter> options);
212
213 static bool is_alias(const option& opt, std::string_view s);
214 };
215}
Concepts which are sufficiently general to appear in the sequoia namespace.
Restriction of Dynamic Graphs to Trees.
Breadth first, depth first and priority searches.
Definition: DynamicTree.hpp:225
Definition: DynamicTree.hpp:176
Parses command line arguments, building outcome from an option forest.
Definition: CommandLineArguments.hpp:176
Class which wraps a std::string and enforces the invariant that the std::string be non-empty.
Definition: CommandLineArguments.hpp:33
Used to build a forest of operations which will be invoked at the end of the parsing process.
Definition: CommandLineArguments.hpp:100
Used to specify a forest of options, against which the runtime commandline arguments are parsed.
Definition: CommandLineArguments.hpp:80
The result of parsing command line arguments to build an operation forest.
Definition: CommandLineArguments.hpp:119