GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
#ifndef SRC_NODE_OPTIONS_H_ |
||
2 |
#define SRC_NODE_OPTIONS_H_ |
||
3 |
|||
4 |
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS |
||
5 |
|||
6 |
#include <memory> |
||
7 |
#include <string> |
||
8 |
#include <unordered_map> |
||
9 |
#include <vector> |
||
10 |
#include "node_constants.h" |
||
11 |
#include "node_mutex.h" |
||
12 |
#include "util.h" |
||
13 |
|||
14 |
namespace node { |
||
15 |
|||
16 |
23672 |
class HostPort { |
|
17 |
public: |
||
18 |
5054 |
HostPort(const std::string& host_name, int port) |
|
19 |
5054 |
: host_name_(host_name), port_(port) {} |
|
20 |
15288 |
HostPort(const HostPort&) = default; |
|
21 |
HostPort& operator=(const HostPort&) = default; |
||
22 |
HostPort(HostPort&&) = default; |
||
23 |
HostPort& operator=(HostPort&&) = default; |
||
24 |
|||
25 |
void set_host(const std::string& host) { host_name_ = host; } |
||
26 |
|||
27 |
80 |
void set_port(int port) { port_ = port; } |
|
28 |
|||
29 |
5178 |
const std::string& host() const { return host_name_; } |
|
30 |
|||
31 |
5262 |
int port() const { |
|
32 |
// TODO(joyeecheung): make port a uint16_t |
||
33 |
✗✓ | 5262 |
CHECK_GE(port_, 0); |
34 |
5262 |
return port_; |
|
35 |
} |
||
36 |
|||
37 |
98 |
void Update(const HostPort& other) { |
|
38 |
✓✓ | 98 |
if (!other.host_name_.empty()) host_name_ = other.host_name_; |
39 |
✓✗ | 98 |
if (other.port_ >= 0) port_ = other.port_; |
40 |
98 |
} |
|
41 |
|||
42 |
private: |
||
43 |
std::string host_name_; |
||
44 |
int port_; |
||
45 |
}; |
||
46 |
|||
47 |
45300 |
class Options { |
|
48 |
public: |
||
49 |
virtual void CheckOptions(std::vector<std::string>* errors) {} |
||
50 |
✗✓ | 37558 |
virtual ~Options() = default; |
51 |
}; |
||
52 |
|||
53 |
struct InspectPublishUid { |
||
54 |
bool console; |
||
55 |
bool http; |
||
56 |
}; |
||
57 |
|||
58 |
// These options are currently essentially per-Environment, but it can be nice |
||
59 |
// to keep them separate since they are a group of options applying to a very |
||
60 |
// specific part of Node. It might also make more sense for them to be |
||
61 |
// per-Isolate, rather than per-Environment. |
||
62 |
✗✓ | 18920 |
class DebugOptions : public Options { |
63 |
public: |
||
64 |
4956 |
DebugOptions() = default; |
|
65 |
10192 |
DebugOptions(const DebugOptions&) = default; |
|
66 |
DebugOptions& operator=(const DebugOptions&) = default; |
||
67 |
DebugOptions(DebugOptions&&) = default; |
||
68 |
DebugOptions& operator=(DebugOptions&&) = default; |
||
69 |
|||
70 |
// --inspect |
||
71 |
bool inspector_enabled = false; |
||
72 |
// --debug |
||
73 |
bool deprecated_debug = false; |
||
74 |
// --inspect-brk |
||
75 |
bool break_first_line = false; |
||
76 |
// --inspect-brk-node |
||
77 |
bool break_node_first_line = false; |
||
78 |
// --inspect-publish-uid |
||
79 |
std::string inspect_publish_uid_string = "stderr,http"; |
||
80 |
|||
81 |
InspectPublishUid inspect_publish_uid; |
||
82 |
|||
83 |
enum { kDefaultInspectorPort = 9229 }; |
||
84 |
|||
85 |
HostPort host_port{"127.0.0.1", kDefaultInspectorPort}; |
||
86 |
|||
87 |
// Used to patch the options as if --inspect-brk is passed. |
||
88 |
32 |
void EnableBreakFirstLine() { |
|
89 |
32 |
inspector_enabled = true; |
|
90 |
32 |
break_first_line = true; |
|
91 |
32 |
} |
|
92 |
|||
93 |
5096 |
bool wait_for_connect() const { |
|
94 |
✓✓✗✓ |
5096 |
return break_first_line || break_node_first_line; |
95 |
} |
||
96 |
|||
97 |
void CheckOptions(std::vector<std::string>* errors) override; |
||
98 |
}; |
||
99 |
|||
100 |
✗✓ | 28390 |
class EnvironmentOptions : public Options { |
101 |
public: |
||
102 |
bool abort_on_uncaught_exception = false; |
||
103 |
bool enable_source_maps = false; |
||
104 |
bool experimental_exports = false; |
||
105 |
bool experimental_modules = false; |
||
106 |
std::string es_module_specifier_resolution; |
||
107 |
bool experimental_wasm_modules = false; |
||
108 |
std::string module_type; |
||
109 |
std::string experimental_policy; |
||
110 |
std::string experimental_policy_integrity; |
||
111 |
bool has_policy_integrity_string; |
||
112 |
bool experimental_repl_await = false; |
||
113 |
bool experimental_vm_modules = false; |
||
114 |
bool expose_internals = false; |
||
115 |
bool frozen_intrinsics = false; |
||
116 |
std::string heap_snapshot_signal; |
||
117 |
bool no_deprecation = false; |
||
118 |
bool no_force_async_hooks_checks = false; |
||
119 |
bool no_warnings = false; |
||
120 |
bool force_context_aware = false; |
||
121 |
bool pending_deprecation = false; |
||
122 |
bool preserve_symlinks = false; |
||
123 |
bool preserve_symlinks_main = false; |
||
124 |
bool prof_process = false; |
||
125 |
#if HAVE_INSPECTOR |
||
126 |
std::string cpu_prof_dir; |
||
127 |
static const uint64_t kDefaultCpuProfInterval = 1000; |
||
128 |
uint64_t cpu_prof_interval = kDefaultCpuProfInterval; |
||
129 |
std::string cpu_prof_name; |
||
130 |
bool cpu_prof = false; |
||
131 |
std::string heap_prof_dir; |
||
132 |
std::string heap_prof_name; |
||
133 |
static const uint64_t kDefaultHeapProfInterval = 512 * 1024; |
||
134 |
uint64_t heap_prof_interval = kDefaultHeapProfInterval; |
||
135 |
bool heap_prof = false; |
||
136 |
#endif // HAVE_INSPECTOR |
||
137 |
std::string redirect_warnings; |
||
138 |
bool test_udp_no_try_send = false; |
||
139 |
bool throw_deprecation = false; |
||
140 |
bool trace_deprecation = false; |
||
141 |
bool trace_sync_io = false; |
||
142 |
bool trace_tls = false; |
||
143 |
bool trace_warnings = false; |
||
144 |
std::string unhandled_rejections; |
||
145 |
std::string userland_loader; |
||
146 |
|||
147 |
bool syntax_check_only = false; |
||
148 |
bool has_eval_string = false; |
||
149 |
#ifdef NODE_REPORT |
||
150 |
bool experimental_report = false; |
||
151 |
#endif // NODE_REPORT |
||
152 |
std::string eval_string; |
||
153 |
bool print_eval = false; |
||
154 |
bool force_repl = false; |
||
155 |
|||
156 |
bool tls_min_v1_0 = false; |
||
157 |
bool tls_min_v1_1 = false; |
||
158 |
bool tls_min_v1_2 = false; |
||
159 |
bool tls_min_v1_3 = false; |
||
160 |
bool tls_max_v1_2 = false; |
||
161 |
bool tls_max_v1_3 = false; |
||
162 |
|||
163 |
std::vector<std::string> preload_modules; |
||
164 |
|||
165 |
std::vector<std::string> user_argv; |
||
166 |
|||
167 |
inline DebugOptions* get_debug_options(); |
||
168 |
inline const DebugOptions& debug_options() const; |
||
169 |
void CheckOptions(std::vector<std::string>* errors) override; |
||
170 |
|||
171 |
private: |
||
172 |
DebugOptions debug_options_; |
||
173 |
}; |
||
174 |
|||
175 |
✓✗ | 29298 |
class PerIsolateOptions : public Options { |
176 |
public: |
||
177 |
std::shared_ptr<EnvironmentOptions> per_env { new EnvironmentOptions() }; |
||
178 |
bool track_heap_objects = false; |
||
179 |
bool no_node_snapshot = false; |
||
180 |
|||
181 |
#ifdef NODE_REPORT |
||
182 |
bool report_uncaught_exception = false; |
||
183 |
bool report_on_signal = false; |
||
184 |
bool report_on_fatalerror = false; |
||
185 |
std::string report_signal; |
||
186 |
std::string report_filename; |
||
187 |
std::string report_directory; |
||
188 |
#endif // NODE_REPORT |
||
189 |
inline EnvironmentOptions* get_per_env_options(); |
||
190 |
void CheckOptions(std::vector<std::string>* errors) override; |
||
191 |
}; |
||
192 |
|||
193 |
✗✓ | 14832 |
class PerProcessOptions : public Options { |
194 |
public: |
||
195 |
std::shared_ptr<PerIsolateOptions> per_isolate { new PerIsolateOptions() }; |
||
196 |
|||
197 |
std::string title; |
||
198 |
std::string trace_event_categories; |
||
199 |
std::string trace_event_file_pattern = "node_trace.${rotation}.log"; |
||
200 |
uint64_t max_http_header_size = 8 * 1024; |
||
201 |
int64_t v8_thread_pool_size = 4; |
||
202 |
bool zero_fill_all_buffers = false; |
||
203 |
bool debug_arraybuffer_allocations = false; |
||
204 |
|||
205 |
std::vector<std::string> security_reverts; |
||
206 |
bool print_bash_completion = false; |
||
207 |
bool print_help = false; |
||
208 |
bool print_v8_help = false; |
||
209 |
bool print_version = false; |
||
210 |
|||
211 |
#ifdef NODE_HAVE_I18N_SUPPORT |
||
212 |
std::string icu_data_dir; |
||
213 |
#endif |
||
214 |
|||
215 |
// TODO(addaleax): Some of these could probably be per-Environment. |
||
216 |
#if HAVE_OPENSSL |
||
217 |
std::string openssl_config; |
||
218 |
std::string tls_cipher_list = DEFAULT_CIPHER_LIST_CORE; |
||
219 |
#ifdef NODE_OPENSSL_CERT_STORE |
||
220 |
bool ssl_openssl_cert_store = true; |
||
221 |
#else |
||
222 |
bool ssl_openssl_cert_store = false; |
||
223 |
#endif |
||
224 |
bool use_openssl_ca = false; |
||
225 |
bool use_bundled_ca = false; |
||
226 |
#if NODE_FIPS_MODE |
||
227 |
bool enable_fips_crypto = false; |
||
228 |
bool force_fips_crypto = false; |
||
229 |
#endif |
||
230 |
#endif |
||
231 |
|||
232 |
#ifdef NODE_REPORT |
||
233 |
std::vector<std::string> cmdline; |
||
234 |
#endif // NODE_REPORT |
||
235 |
|||
236 |
inline PerIsolateOptions* get_per_isolate_options(); |
||
237 |
void CheckOptions(std::vector<std::string>* errors) override; |
||
238 |
}; |
||
239 |
|||
240 |
// The actual options parser, as opposed to the structs containing them: |
||
241 |
|||
242 |
namespace options_parser { |
||
243 |
|||
244 |
HostPort SplitHostPort(const std::string& arg, |
||
245 |
std::vector<std::string>* errors); |
||
246 |
void GetOptions(const v8::FunctionCallbackInfo<v8::Value>& args); |
||
247 |
|||
248 |
enum OptionEnvvarSettings { |
||
249 |
kAllowedInEnvironment, |
||
250 |
kDisallowedInEnvironment |
||
251 |
}; |
||
252 |
|||
253 |
enum OptionType { |
||
254 |
kNoOp, |
||
255 |
kV8Option, |
||
256 |
kBoolean, |
||
257 |
kInteger, |
||
258 |
kUInteger, |
||
259 |
kString, |
||
260 |
kHostPort, |
||
261 |
kStringList, |
||
262 |
}; |
||
263 |
|||
264 |
template <typename Options> |
||
265 |
19776 |
class OptionsParser { |
|
266 |
public: |
||
267 |
✗✓✗✓ ✗✓✗✓ |
19776 |
virtual ~OptionsParser() = default; |
268 |
|||
269 |
typedef Options TargetType; |
||
270 |
|||
271 |
struct NoOp {}; |
||
272 |
struct V8Option {}; |
||
273 |
|||
274 |
// These methods add a single option to the parser. Optionally, it can be |
||
275 |
// specified whether the option should be allowed from environment variable |
||
276 |
// sources (i.e. NODE_OPTIONS). |
||
277 |
void AddOption(const char* name, |
||
278 |
const char* help_text, |
||
279 |
bool Options::* field, |
||
280 |
OptionEnvvarSettings env_setting = kDisallowedInEnvironment); |
||
281 |
void AddOption(const char* name, |
||
282 |
const char* help_text, |
||
283 |
uint64_t Options::* field, |
||
284 |
OptionEnvvarSettings env_setting = kDisallowedInEnvironment); |
||
285 |
void AddOption(const char* name, |
||
286 |
const char* help_text, |
||
287 |
int64_t Options::* field, |
||
288 |
OptionEnvvarSettings env_setting = kDisallowedInEnvironment); |
||
289 |
void AddOption(const char* name, |
||
290 |
const char* help_text, |
||
291 |
std::string Options::* field, |
||
292 |
OptionEnvvarSettings env_setting = kDisallowedInEnvironment); |
||
293 |
void AddOption(const char* name, |
||
294 |
const char* help_text, |
||
295 |
std::vector<std::string> Options::* field, |
||
296 |
OptionEnvvarSettings env_setting = kDisallowedInEnvironment); |
||
297 |
void AddOption(const char* name, |
||
298 |
const char* help_text, |
||
299 |
HostPort Options::* field, |
||
300 |
OptionEnvvarSettings env_setting = kDisallowedInEnvironment); |
||
301 |
void AddOption(const char* name, |
||
302 |
const char* help_text, |
||
303 |
NoOp no_op_tag, |
||
304 |
OptionEnvvarSettings env_setting = kDisallowedInEnvironment); |
||
305 |
void AddOption(const char* name, |
||
306 |
const char* help_text, |
||
307 |
V8Option v8_option_tag, |
||
308 |
OptionEnvvarSettings env_setting = kDisallowedInEnvironment); |
||
309 |
|||
310 |
// Adds aliases. An alias can be of the form "--option-a" -> "--option-b", |
||
311 |
// or have a more complex group expansion, like |
||
312 |
// "--option-a" -> { "--option-b", "--harmony-foobar", "--eval", "42" } |
||
313 |
// If `from` has the form "--option-a=", the alias will only be expanded if |
||
314 |
// the option is presented in that form (i.e. with a '='). |
||
315 |
// If `from` has the form "--option-a <arg>", the alias will only be expanded |
||
316 |
// if the option has a non-option argument (not starting with -) following it. |
||
317 |
void AddAlias(const char* from, const char* to); |
||
318 |
void AddAlias(const char* from, const std::vector<std::string>& to); |
||
319 |
void AddAlias(const char* from, |
||
320 |
const std::initializer_list<std::string>& to); |
||
321 |
|||
322 |
// Add implications from some arbitrary option to a boolean one, either |
||
323 |
// in a way that makes `from` set `to` to true or to false. |
||
324 |
void Implies(const char* from, const char* to); |
||
325 |
void ImpliesNot(const char* from, const char* to); |
||
326 |
|||
327 |
// Insert options from another options parser into this one, along with |
||
328 |
// a method that yields the target options type from this parser's options |
||
329 |
// type. |
||
330 |
template <typename ChildOptions> |
||
331 |
void Insert(const OptionsParser<ChildOptions>& child_options_parser, |
||
332 |
ChildOptions* (Options::* get_child)()); |
||
333 |
|||
334 |
// Parse a sequence of options into an options struct, a list of |
||
335 |
// arguments that were parsed as options, a list of unknown/JS engine options, |
||
336 |
// and leave the remainder in the input `args` vector. |
||
337 |
// |
||
338 |
// For example, an `args` input of |
||
339 |
// |
||
340 |
// node --foo --harmony-bar --fizzle=42 -- /path/to/cow moo |
||
341 |
// |
||
342 |
// expands as |
||
343 |
// |
||
344 |
// - `args` -> { "node", "/path/to/cow", "moo" } |
||
345 |
// - `exec_args` -> { "--foo", "--harmony-bar", "--fizzle=42" } |
||
346 |
// - `v8_args` -> `{ "node", "--harmony-bar" } |
||
347 |
// - `options->foo == true`, `options->fizzle == 42`. |
||
348 |
// |
||
349 |
// If `*error` is set, the result of the parsing should be discarded and the |
||
350 |
// contents of any of the argument vectors should be considered undefined. |
||
351 |
void Parse(std::vector<std::string>* const args, |
||
352 |
std::vector<std::string>* const exec_args, |
||
353 |
std::vector<std::string>* const v8_args, |
||
354 |
Options* const options, |
||
355 |
OptionEnvvarSettings required_env_settings, |
||
356 |
std::vector<std::string>* const errors) const; |
||
357 |
|||
358 |
private: |
||
359 |
// We support the wide variety of different option types by remembering |
||
360 |
// how to access them, given a certain `Options` struct. |
||
361 |
|||
362 |
// Represents a field within `Options`. |
||
363 |
1211280 |
class BaseOptionField { |
|
364 |
public: |
||
365 |
✗✓✗✓ ✗✓✗✓ |
1211280 |
virtual ~BaseOptionField() = default; |
366 |
virtual void* LookupImpl(Options* options) const = 0; |
||
367 |
|||
368 |
template <typename T> |
||
369 |
435212 |
inline T* Lookup(Options* options) const { |
|
370 |
435212 |
return static_cast<T*>(LookupImpl(options)); |
|
371 |
} |
||
372 |
}; |
||
373 |
|||
374 |
// Represents a field of type T within `Options` that can be looked up |
||
375 |
// as a C++ member field. |
||
376 |
template <typename T> |
||
377 |
✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ |
420240 |
class SimpleOptionField : public BaseOptionField { |
378 |
public: |
||
379 |
420240 |
explicit SimpleOptionField(T Options::* field) : field_(field) {} |
|
380 |
435212 |
void* LookupImpl(Options* options) const override { |
|
381 |
435212 |
return static_cast<void*>(&(options->*field_)); |
|
382 |
} |
||
383 |
|||
384 |
private: |
||
385 |
T Options::* field_; |
||
386 |
}; |
||
387 |
|||
388 |
template <typename T> |
||
389 |
434738 |
inline T* Lookup(std::shared_ptr<BaseOptionField> field, |
|
390 |
Options* options) const { |
||
391 |
434738 |
return field->template Lookup<T>(options); |
|
392 |
} |
||
393 |
|||
394 |
// An option consists of: |
||
395 |
// - A type. |
||
396 |
// - A way to store/access the property value. |
||
397 |
// - The information of whether it may occur in an env var or not. |
||
398 |
5057712 |
struct OptionInfo { |
|
399 |
OptionType type; |
||
400 |
std::shared_ptr<BaseOptionField> field; |
||
401 |
OptionEnvvarSettings env_setting; |
||
402 |
std::string help_text; |
||
403 |
}; |
||
404 |
|||
405 |
// An implied option is composed of the information on where to store a |
||
406 |
// specific boolean value (if another specific option is encountered). |
||
407 |
440016 |
struct Implication { |
|
408 |
std::shared_ptr<BaseOptionField> target_field; |
||
409 |
bool target_value; |
||
410 |
}; |
||
411 |
|||
412 |
// These are helpers that make `Insert()` support properties of other |
||
413 |
// options structs, if we know how to access them. |
||
414 |
template <typename OriginalField, typename ChildOptions> |
||
415 |
static auto Convert( |
||
416 |
std::shared_ptr<OriginalField> original, |
||
417 |
ChildOptions* (Options::* get_child)()); |
||
418 |
template <typename ChildOptions> |
||
419 |
static auto Convert( |
||
420 |
typename OptionsParser<ChildOptions>::OptionInfo original, |
||
421 |
ChildOptions* (Options::* get_child)()); |
||
422 |
template <typename ChildOptions> |
||
423 |
static auto Convert( |
||
424 |
typename OptionsParser<ChildOptions>::Implication original, |
||
425 |
ChildOptions* (Options::* get_child)()); |
||
426 |
|||
427 |
std::unordered_map<std::string, OptionInfo> options_; |
||
428 |
std::unordered_map<std::string, std::vector<std::string>> aliases_; |
||
429 |
std::unordered_multimap<std::string, Implication> implications_; |
||
430 |
|||
431 |
template <typename OtherOptions> |
||
432 |
friend class OptionsParser; |
||
433 |
|||
434 |
friend void GetOptions(const v8::FunctionCallbackInfo<v8::Value>& args); |
||
435 |
}; |
||
436 |
|||
437 |
using StringVector = std::vector<std::string>; |
||
438 |
template <class OptionsType, class = Options> |
||
439 |
void Parse( |
||
440 |
StringVector* const args, StringVector* const exec_args, |
||
441 |
StringVector* const v8_args, OptionsType* const options, |
||
442 |
OptionEnvvarSettings required_env_settings, StringVector* const errors); |
||
443 |
|||
444 |
} // namespace options_parser |
||
445 |
|||
446 |
namespace per_process { |
||
447 |
|||
448 |
extern Mutex cli_options_mutex; |
||
449 |
extern std::shared_ptr<PerProcessOptions> cli_options; |
||
450 |
|||
451 |
} // namespace per_process |
||
452 |
} // namespace node |
||
453 |
|||
454 |
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS |
||
455 |
|||
456 |
#endif // SRC_NODE_OPTIONS_H_ |
Generated by: GCOVR (Version 3.4) |