FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
arg_parser.cpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5
6#include <kernel/util/arg_parser.hpp>
7
8#include <numeric>
9
10namespace FEAT::Intern
11{
19 {
20 if(!custom_name.empty())
21 {
22 return custom_name;
23 }
24 if(!long_flag.empty())
25 {
26 return long_flag.substr(2);
27 }
28
29 if(!short_flag.empty())
30 {
31 return short_flag.substr(1);
32 }
33
34 if(!property_path.empty())
35 {
36 return property_path;
37 }
38
39 if(!environment_variable.empty())
40 {
41 return environment_variable;
42 }
43
44 return "<anonymous>";
45 }
46
48 void ParameterCore::add_argument(const String& s, int incoming_priority)
49 {
50 if(priority < incoming_priority)
51 {
52 // New argument is of higher priority than all previous arguments
53 // Clear the list and set new priority
54 arguments.clear();
55 arguments.push_back(s.trim());
56 priority = incoming_priority;
57 }
58 else if(priority == incoming_priority)
59 {
60 // New argument is of same priority
61 // Store it for now
62 arguments.push_back(s.trim());
63 }
64 }
65
66 void ParameterCore::validate(std::deque<String>& errors) const
67 {
68 if(required && !set_by_user)
69 {
70 errors.push_back("Error: Parameter " + name() + " not given, but is required!");
71 return;
72 }
73
74 if(validator)
75 {
76 try
77 {
78 validator(value);
79 }
80 catch(std::bad_any_cast& e)
81 {
82 XABORTM(e.what());
83 }
84 catch(std::invalid_argument& e)
85 {
86 errors.push_back("Error: Validation of parameter " + name() + " failed with message: " + e.what());
87 }
88 }
89
90 for(const auto& [core, condition] : needs)
91 {
92 if(core.expired())
93 {
94 XABORTM("Expired weak ptr to parameter core of " + name());
95 }
96
97 auto ptr = core.lock();
98
99 if(set_by_user && condition(value))
100 {
101 if(!ptr->set_by_user)
102 {
103 errors.push_back(
104 "Error: Parameter " + name() + " needs parameter " + ptr->name() + ", but parameter " + ptr->name() +
105 " was not set by user");
106 }
107 }
108 }
109 }
110
111 void ParameterCore::parse(std::deque<String>& errors)
112 {
113 if(arguments.empty())
114 {
115 // Nothing to parse
116 return;
117 }
118
119 set_by_user = true;
120
121 // Merge arguments of collection options
122 // NOTE: This is slightly inefficient, because
123 // the collection parser is just going to split the string
124 // by whitespace anyway. But CLI arguments come pre-split
125 // and this way we can handle all argument sources with the same parser
126 if(type == ParameterType::collection_option)
127 {
128 String merged = std::accumulate(
129 arguments.begin(),
130 arguments.end(),
131 String(""),
132 [](const String& a, const String& b) { return a + " " + b; });
133
134 // Replace arguments with merged version
135 arguments.clear();
136 arguments.push_back(merged.trim());
137 }
138
139 if(arguments.size() > 1)
140 {
141 errors.push_back("Error: Parameter " + name() + " was set multiple times. Only the first value is considered!");
142 }
143
144 if(!parser)
145 {
146 errors.push_back(
147 "Error: No parser for parameter " + name() +
148 ". Ensure operator>> is available for your type or set a custom parser!");
149 return;
150 }
151
152 try
153 {
154 parser(value, arguments.front());
155 }
156 catch(std::bad_any_cast& e)
157 {
158 XABORTM(e.what());
159 }
160 catch(std::invalid_argument& e)
161 {
162 errors.push_back("Error: Parsing for parameter " + name() + " failed with message: " + e.what());
163 }
164 }
165
168 {
169 value = default_value;
170 priority = 0;
171 arguments.clear();
172 set_by_user = false;
173 }
174} // namespace FEAT
#define XABORTM(msg)
Abortion macro definition with custom message.
Definition: assertion.hpp:192
String name() const
Tries to create a user-readable name for this parameter.
Definition: arg_parser.cpp:18
void parse(std::deque< String > &errors)
Parse this parameter.
Definition: arg_parser.cpp:111
void validate(std::deque< String > &errors) const
Validate this parameter.
Definition: arg_parser.cpp:66
void reset()
Reset this parameter to default.
Definition: arg_parser.cpp:167
void add_argument(const String &s, int incoming_priority)
Add an argument to this parameter.
Definition: arg_parser.cpp:48
String class implementation.
Definition: string.hpp:47
String trim(const String &charset) const
Trims the string.
Definition: string.hpp:328