Coverage Report

Created: 2025-10-31 09:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/node/src/node_options-inl.h
Line
Count
Source
1
#ifndef SRC_NODE_OPTIONS_INL_H_
2
#define SRC_NODE_OPTIONS_INL_H_
3
4
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5
6
#include <algorithm>
7
#include <cstdlib>
8
#include <ranges>
9
#include "node_options.h"
10
#include "util.h"
11
12
namespace node {
13
14
5.18k
PerIsolateOptions* PerProcessOptions::get_per_isolate_options() {
15
5.18k
  return per_isolate.get();
16
5.18k
}
17
18
4.83k
EnvironmentOptions* PerIsolateOptions::get_per_env_options() {
19
4.83k
  return per_env.get();
20
4.83k
}
21
22
35
std::shared_ptr<PerIsolateOptions> PerIsolateOptions::Clone() const {
23
35
  auto options =
24
35
      std::shared_ptr<PerIsolateOptions>(new PerIsolateOptions(*this));
25
35
  options->per_env = std::make_shared<EnvironmentOptions>(*per_env);
26
35
  return options;
27
35
}
28
29
namespace options_parser {
30
31
template <typename Options>
32
void OptionsParser<Options>::AddOption(const char* name,
33
                                       const char* help_text,
34
                                       bool Options::*field,
35
                                       OptionEnvvarSettings env_setting,
36
                                       bool default_is_true,
37
8.13k
                                       OptionNamespaces namespace_id) {
38
8.13k
  options_.emplace(name,
39
8.13k
                   OptionInfo{kBoolean,
40
8.13k
                              std::make_shared<SimpleOptionField<bool>>(field),
41
8.13k
                              env_setting,
42
8.13k
                              help_text,
43
8.13k
                              default_is_true,
44
8.13k
                              NamespaceEnumToString(namespace_id)});
45
8.13k
}
node::options_parser::OptionsParser<node::DebugOptions>::AddOption(char const*, char const*, bool node::DebugOptions::*, node::OptionEnvvarSettings, bool, node::options_parser::OptionNamespaces)
Line
Count
Source
37
432
                                       OptionNamespaces namespace_id) {
38
432
  options_.emplace(name,
39
432
                   OptionInfo{kBoolean,
40
432
                              std::make_shared<SimpleOptionField<bool>>(field),
41
432
                              env_setting,
42
432
                              help_text,
43
432
                              default_is_true,
44
432
                              NamespaceEnumToString(namespace_id)});
45
432
}
node::options_parser::OptionsParser<node::EnvironmentOptions>::AddOption(char const*, char const*, bool node::EnvironmentOptions::*, node::OptionEnvvarSettings, bool, node::options_parser::OptionNamespaces)
Line
Count
Source
37
5.97k
                                       OptionNamespaces namespace_id) {
38
5.97k
  options_.emplace(name,
39
5.97k
                   OptionInfo{kBoolean,
40
5.97k
                              std::make_shared<SimpleOptionField<bool>>(field),
41
5.97k
                              env_setting,
42
5.97k
                              help_text,
43
5.97k
                              default_is_true,
44
5.97k
                              NamespaceEnumToString(namespace_id)});
45
5.97k
}
node::options_parser::OptionsParser<node::PerIsolateOptions>::AddOption(char const*, char const*, bool node::PerIsolateOptions::*, node::OptionEnvvarSettings, bool, node::options_parser::OptionNamespaces)
Line
Count
Source
37
360
                                       OptionNamespaces namespace_id) {
38
360
  options_.emplace(name,
39
360
                   OptionInfo{kBoolean,
40
360
                              std::make_shared<SimpleOptionField<bool>>(field),
41
360
                              env_setting,
42
360
                              help_text,
43
360
                              default_is_true,
44
360
                              NamespaceEnumToString(namespace_id)});
45
360
}
node::options_parser::OptionsParser<node::PerProcessOptions>::AddOption(char const*, char const*, bool node::PerProcessOptions::*, node::OptionEnvvarSettings, bool, node::options_parser::OptionNamespaces)
Line
Count
Source
37
1.36k
                                       OptionNamespaces namespace_id) {
38
1.36k
  options_.emplace(name,
39
1.36k
                   OptionInfo{kBoolean,
40
1.36k
                              std::make_shared<SimpleOptionField<bool>>(field),
41
1.36k
                              env_setting,
42
1.36k
                              help_text,
43
1.36k
                              default_is_true,
44
1.36k
                              NamespaceEnumToString(namespace_id)});
45
1.36k
}
46
47
template <typename Options>
48
void OptionsParser<Options>::AddOption(const char* name,
49
                                       const char* help_text,
50
                                       uint64_t Options::*field,
51
                                       OptionEnvvarSettings env_setting,
52
648
                                       OptionNamespaces namespace_id) {
53
648
  options_.emplace(
54
648
      name,
55
648
      OptionInfo{kUInteger,
56
648
                 std::make_shared<SimpleOptionField<uint64_t>>(field),
57
648
                 env_setting,
58
648
                 help_text,
59
648
                 false,
60
648
                 NamespaceEnumToString(namespace_id)});
61
648
}
62
63
template <typename Options>
64
void OptionsParser<Options>::AddOption(const char* name,
65
                                       const char* help_text,
66
                                       int64_t Options::*field,
67
                                       OptionEnvvarSettings env_setting,
68
360
                                       OptionNamespaces namespace_id) {
69
360
  options_.emplace(
70
360
      name,
71
360
      OptionInfo{kInteger,
72
360
                 std::make_shared<SimpleOptionField<int64_t>>(field),
73
360
                 env_setting,
74
360
                 help_text,
75
360
                 false,
76
360
                 NamespaceEnumToString(namespace_id)});
77
360
}
node::options_parser::OptionsParser<node::EnvironmentOptions>::AddOption(char const*, char const*, long node::EnvironmentOptions::*, node::OptionEnvvarSettings, node::options_parser::OptionNamespaces)
Line
Count
Source
68
72
                                       OptionNamespaces namespace_id) {
69
72
  options_.emplace(
70
72
      name,
71
72
      OptionInfo{kInteger,
72
72
                 std::make_shared<SimpleOptionField<int64_t>>(field),
73
72
                 env_setting,
74
72
                 help_text,
75
72
                 false,
76
72
                 NamespaceEnumToString(namespace_id)});
77
72
}
node::options_parser::OptionsParser<node::PerIsolateOptions>::AddOption(char const*, char const*, long node::PerIsolateOptions::*, node::OptionEnvvarSettings, node::options_parser::OptionNamespaces)
Line
Count
Source
68
72
                                       OptionNamespaces namespace_id) {
69
72
  options_.emplace(
70
72
      name,
71
72
      OptionInfo{kInteger,
72
72
                 std::make_shared<SimpleOptionField<int64_t>>(field),
73
72
                 env_setting,
74
72
                 help_text,
75
72
                 false,
76
72
                 NamespaceEnumToString(namespace_id)});
77
72
}
node::options_parser::OptionsParser<node::PerProcessOptions>::AddOption(char const*, char const*, long node::PerProcessOptions::*, node::OptionEnvvarSettings, node::options_parser::OptionNamespaces)
Line
Count
Source
68
216
                                       OptionNamespaces namespace_id) {
69
216
  options_.emplace(
70
216
      name,
71
216
      OptionInfo{kInteger,
72
216
                 std::make_shared<SimpleOptionField<int64_t>>(field),
73
216
                 env_setting,
74
216
                 help_text,
75
216
                 false,
76
216
                 NamespaceEnumToString(namespace_id)});
77
216
}
78
79
template <typename Options>
80
void OptionsParser<Options>::AddOption(const char* name,
81
                                       const char* help_text,
82
                                       std::string Options::*field,
83
                                       OptionEnvvarSettings env_setting,
84
2.80k
                                       OptionNamespaces namespace_id) {
85
2.80k
  options_.emplace(
86
2.80k
      name,
87
2.80k
      OptionInfo{kString,
88
2.80k
                 std::make_shared<SimpleOptionField<std::string>>(field),
89
2.80k
                 env_setting,
90
2.80k
                 help_text,
91
2.80k
                 false,
92
2.80k
                 NamespaceEnumToString(namespace_id)});
93
2.80k
}
node::options_parser::OptionsParser<node::DebugOptions>::AddOption(char const*, char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > node::DebugOptions::*, node::OptionEnvvarSettings, node::options_parser::OptionNamespaces)
Line
Count
Source
84
72
                                       OptionNamespaces namespace_id) {
85
72
  options_.emplace(
86
72
      name,
87
72
      OptionInfo{kString,
88
72
                 std::make_shared<SimpleOptionField<std::string>>(field),
89
72
                 env_setting,
90
72
                 help_text,
91
72
                 false,
92
72
                 NamespaceEnumToString(namespace_id)});
93
72
}
node::options_parser::OptionsParser<node::EnvironmentOptions>::AddOption(char const*, char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > node::EnvironmentOptions::*, node::OptionEnvvarSettings, node::options_parser::OptionNamespaces)
Line
Count
Source
84
1.58k
                                       OptionNamespaces namespace_id) {
85
1.58k
  options_.emplace(
86
1.58k
      name,
87
1.58k
      OptionInfo{kString,
88
1.58k
                 std::make_shared<SimpleOptionField<std::string>>(field),
89
1.58k
                 env_setting,
90
1.58k
                 help_text,
91
1.58k
                 false,
92
1.58k
                 NamespaceEnumToString(namespace_id)});
93
1.58k
}
node::options_parser::OptionsParser<node::PerIsolateOptions>::AddOption(char const*, char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > node::PerIsolateOptions::*, node::OptionEnvvarSettings, node::options_parser::OptionNamespaces)
Line
Count
Source
84
216
                                       OptionNamespaces namespace_id) {
85
216
  options_.emplace(
86
216
      name,
87
216
      OptionInfo{kString,
88
216
                 std::make_shared<SimpleOptionField<std::string>>(field),
89
216
                 env_setting,
90
216
                 help_text,
91
216
                 false,
92
216
                 NamespaceEnumToString(namespace_id)});
93
216
}
node::options_parser::OptionsParser<node::PerProcessOptions>::AddOption(char const*, char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > node::PerProcessOptions::*, node::OptionEnvvarSettings, node::options_parser::OptionNamespaces)
Line
Count
Source
84
936
                                       OptionNamespaces namespace_id) {
85
936
  options_.emplace(
86
936
      name,
87
936
      OptionInfo{kString,
88
936
                 std::make_shared<SimpleOptionField<std::string>>(field),
89
936
                 env_setting,
90
936
                 help_text,
91
936
                 false,
92
936
                 NamespaceEnumToString(namespace_id)});
93
936
}
94
95
template <typename Options>
96
void OptionsParser<Options>::AddOption(const char* name,
97
                                       const char* help_text,
98
                                       std::vector<std::string> Options::*field,
99
                                       OptionEnvvarSettings env_setting,
100
1.08k
                                       OptionNamespaces namespace_id) {
101
1.08k
  options_.emplace(
102
1.08k
      name,
103
1.08k
      OptionInfo{
104
1.08k
          kStringList,
105
1.08k
          std::make_shared<SimpleOptionField<std::vector<std::string>>>(field),
106
1.08k
          env_setting,
107
1.08k
          help_text,
108
1.08k
          false,
109
1.08k
          NamespaceEnumToString(namespace_id)});
110
1.08k
}
node::options_parser::OptionsParser<node::EnvironmentOptions>::AddOption(char const*, char const*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > node::EnvironmentOptions::*, node::OptionEnvvarSettings, node::options_parser::OptionNamespaces)
Line
Count
Source
100
1.00k
                                       OptionNamespaces namespace_id) {
101
1.00k
  options_.emplace(
102
1.00k
      name,
103
1.00k
      OptionInfo{
104
1.00k
          kStringList,
105
1.00k
          std::make_shared<SimpleOptionField<std::vector<std::string>>>(field),
106
1.00k
          env_setting,
107
1.00k
          help_text,
108
1.00k
          false,
109
1.00k
          NamespaceEnumToString(namespace_id)});
110
1.00k
}
node::options_parser::OptionsParser<node::PerProcessOptions>::AddOption(char const*, char const*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > node::PerProcessOptions::*, node::OptionEnvvarSettings, node::options_parser::OptionNamespaces)
Line
Count
Source
100
72
                                       OptionNamespaces namespace_id) {
101
72
  options_.emplace(
102
72
      name,
103
72
      OptionInfo{
104
72
          kStringList,
105
72
          std::make_shared<SimpleOptionField<std::vector<std::string>>>(field),
106
72
          env_setting,
107
72
          help_text,
108
72
          false,
109
72
          NamespaceEnumToString(namespace_id)});
110
72
}
111
112
template <typename Options>
113
void OptionsParser<Options>::AddOption(const char* name,
114
                                       const char* help_text,
115
                                       HostPort Options::*field,
116
                                       OptionEnvvarSettings env_setting,
117
72
                                       OptionNamespaces namespace_id) {
118
72
  options_.emplace(
119
72
      name,
120
72
      OptionInfo{kHostPort,
121
72
                 std::make_shared<SimpleOptionField<HostPort>>(field),
122
72
                 env_setting,
123
72
                 help_text,
124
72
                 false,
125
72
                 NamespaceEnumToString(namespace_id)});
126
72
}
127
128
template <typename Options>
129
void OptionsParser<Options>::AddOption(const char* name,
130
                                       const char* help_text,
131
                                       NoOp no_op_tag,
132
                                       OptionEnvvarSettings env_setting,
133
1.15k
                                       OptionNamespaces namespace_id) {
134
1.15k
  options_.emplace(name,
135
1.15k
                   OptionInfo{kNoOp,
136
1.15k
                              nullptr,
137
1.15k
                              env_setting,
138
1.15k
                              help_text,
139
1.15k
                              false,
140
1.15k
                              NamespaceEnumToString(namespace_id)});
141
1.15k
}
node::options_parser::OptionsParser<node::EnvironmentOptions>::AddOption(char const*, char const*, node::options_parser::OptionsParser<node::EnvironmentOptions>::NoOp, node::OptionEnvvarSettings, node::options_parser::OptionNamespaces)
Line
Count
Source
133
1.00k
                                       OptionNamespaces namespace_id) {
134
1.00k
  options_.emplace(name,
135
1.00k
                   OptionInfo{kNoOp,
136
1.00k
                              nullptr,
137
1.00k
                              env_setting,
138
1.00k
                              help_text,
139
1.00k
                              false,
140
1.00k
                              NamespaceEnumToString(namespace_id)});
141
1.00k
}
node::options_parser::OptionsParser<node::PerIsolateOptions>::AddOption(char const*, char const*, node::options_parser::OptionsParser<node::PerIsolateOptions>::NoOp, node::OptionEnvvarSettings, node::options_parser::OptionNamespaces)
Line
Count
Source
133
72
                                       OptionNamespaces namespace_id) {
134
72
  options_.emplace(name,
135
72
                   OptionInfo{kNoOp,
136
72
                              nullptr,
137
72
                              env_setting,
138
72
                              help_text,
139
72
                              false,
140
72
                              NamespaceEnumToString(namespace_id)});
141
72
}
node::options_parser::OptionsParser<node::PerProcessOptions>::AddOption(char const*, char const*, node::options_parser::OptionsParser<node::PerProcessOptions>::NoOp, node::OptionEnvvarSettings, node::options_parser::OptionNamespaces)
Line
Count
Source
133
72
                                       OptionNamespaces namespace_id) {
134
72
  options_.emplace(name,
135
72
                   OptionInfo{kNoOp,
136
72
                              nullptr,
137
72
                              env_setting,
138
72
                              help_text,
139
72
                              false,
140
72
                              NamespaceEnumToString(namespace_id)});
141
72
}
142
143
template <typename Options>
144
void OptionsParser<Options>::AddOption(const char* name,
145
                                       const char* help_text,
146
                                       V8Option v8_option_tag,
147
                                       OptionEnvvarSettings env_setting,
148
1.00k
                                       OptionNamespaces namespace_id) {
149
1.00k
  options_.emplace(name,
150
1.00k
                   OptionInfo{kV8Option,
151
1.00k
                              nullptr,
152
1.00k
                              env_setting,
153
1.00k
                              help_text,
154
1.00k
                              false,
155
1.00k
                              NamespaceEnumToString(namespace_id)});
156
1.00k
}
node::options_parser::OptionsParser<node::EnvironmentOptions>::AddOption(char const*, char const*, node::options_parser::OptionsParser<node::EnvironmentOptions>::V8Option, node::OptionEnvvarSettings, node::options_parser::OptionNamespaces)
Line
Count
Source
148
144
                                       OptionNamespaces namespace_id) {
149
144
  options_.emplace(name,
150
144
                   OptionInfo{kV8Option,
151
144
                              nullptr,
152
144
                              env_setting,
153
144
                              help_text,
154
144
                              false,
155
144
                              NamespaceEnumToString(namespace_id)});
156
144
}
node::options_parser::OptionsParser<node::PerIsolateOptions>::AddOption(char const*, char const*, node::options_parser::OptionsParser<node::PerIsolateOptions>::V8Option, node::OptionEnvvarSettings, node::options_parser::OptionNamespaces)
Line
Count
Source
148
864
                                       OptionNamespaces namespace_id) {
149
864
  options_.emplace(name,
150
864
                   OptionInfo{kV8Option,
151
864
                              nullptr,
152
864
                              env_setting,
153
864
                              help_text,
154
864
                              false,
155
864
                              NamespaceEnumToString(namespace_id)});
156
864
}
157
158
template <typename Options>
159
void OptionsParser<Options>::AddAlias(const char* from,
160
1.36k
                                      const char* to) {
161
1.36k
  aliases_[from] = { to };
162
1.36k
}
node::options_parser::OptionsParser<node::DebugOptions>::AddAlias(char const*, char const*)
Line
Count
Source
160
216
                                      const char* to) {
161
216
  aliases_[from] = { to };
162
216
}
node::options_parser::OptionsParser<node::EnvironmentOptions>::AddAlias(char const*, char const*)
Line
Count
Source
160
864
                                      const char* to) {
161
864
  aliases_[from] = { to };
162
864
}
node::options_parser::OptionsParser<node::PerProcessOptions>::AddAlias(char const*, char const*)
Line
Count
Source
160
288
                                      const char* to) {
161
288
  aliases_[from] = { to };
162
288
}
163
164
template <typename Options>
165
void OptionsParser<Options>::AddAlias(const char* from,
166
504
                                      const std::vector<std::string>& to) {
167
504
  aliases_[from] = to;
168
504
}
node::options_parser::OptionsParser<node::DebugOptions>::AddAlias(char const*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&)
Line
Count
Source
166
288
                                      const std::vector<std::string>& to) {
167
288
  aliases_[from] = to;
168
288
}
node::options_parser::OptionsParser<node::EnvironmentOptions>::AddAlias(char const*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&)
Line
Count
Source
166
144
                                      const std::vector<std::string>& to) {
167
144
  aliases_[from] = to;
168
144
}
node::options_parser::OptionsParser<node::PerProcessOptions>::AddAlias(char const*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&)
Line
Count
Source
166
72
                                      const std::vector<std::string>& to) {
167
72
  aliases_[from] = to;
168
72
}
169
170
template <typename Options>
171
void OptionsParser<Options>::AddAlias(
172
    const char* from,
173
504
    const std::initializer_list<std::string>& to) {
174
504
  AddAlias(from, std::vector<std::string>(to));
175
504
}
node::options_parser::OptionsParser<node::DebugOptions>::AddAlias(char const*, std::initializer_list<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > const&)
Line
Count
Source
173
288
    const std::initializer_list<std::string>& to) {
174
288
  AddAlias(from, std::vector<std::string>(to));
175
288
}
node::options_parser::OptionsParser<node::EnvironmentOptions>::AddAlias(char const*, std::initializer_list<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > const&)
Line
Count
Source
173
144
    const std::initializer_list<std::string>& to) {
174
144
  AddAlias(from, std::vector<std::string>(to));
175
144
}
node::options_parser::OptionsParser<node::PerProcessOptions>::AddAlias(char const*, std::initializer_list<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > const&)
Line
Count
Source
173
72
    const std::initializer_list<std::string>& to) {
174
72
  AddAlias(from, std::vector<std::string>(to));
175
72
}
176
177
template <typename Options>
178
void OptionsParser<Options>::Implies(const char* from,
179
1.29k
                                     const char* to) {
180
1.29k
  auto it = options_.find(to);
181
1.29k
  CHECK_NE(it, options_.end());
182
1.29k
  CHECK(it->second.type == kBoolean || it->second.type == kV8Option);
183
1.29k
  implications_.emplace(
184
1.29k
      from, Implication{it->second.type, to, it->second.field, true});
185
1.29k
}
node::options_parser::OptionsParser<node::DebugOptions>::Implies(char const*, char const*)
Line
Count
Source
179
216
                                     const char* to) {
180
216
  auto it = options_.find(to);
181
216
  CHECK_NE(it, options_.end());
182
216
  CHECK(it->second.type == kBoolean || it->second.type == kV8Option);
183
216
  implications_.emplace(
184
216
      from, Implication{it->second.type, to, it->second.field, true});
185
216
}
node::options_parser::OptionsParser<node::EnvironmentOptions>::Implies(char const*, char const*)
Line
Count
Source
179
576
                                     const char* to) {
180
576
  auto it = options_.find(to);
181
576
  CHECK_NE(it, options_.end());
182
576
  CHECK(it->second.type == kBoolean || it->second.type == kV8Option);
183
576
  implications_.emplace(
184
576
      from, Implication{it->second.type, to, it->second.field, true});
185
576
}
node::options_parser::OptionsParser<node::PerIsolateOptions>::Implies(char const*, char const*)
Line
Count
Source
179
288
                                     const char* to) {
180
288
  auto it = options_.find(to);
181
288
  CHECK_NE(it, options_.end());
182
288
  CHECK(it->second.type == kBoolean || it->second.type == kV8Option);
183
288
  implications_.emplace(
184
288
      from, Implication{it->second.type, to, it->second.field, true});
185
288
}
node::options_parser::OptionsParser<node::PerProcessOptions>::Implies(char const*, char const*)
Line
Count
Source
179
216
                                     const char* to) {
180
216
  auto it = options_.find(to);
181
216
  CHECK_NE(it, options_.end());
182
216
  CHECK(it->second.type == kBoolean || it->second.type == kV8Option);
183
216
  implications_.emplace(
184
216
      from, Implication{it->second.type, to, it->second.field, true});
185
216
}
186
187
template <typename Options>
188
void OptionsParser<Options>::ImpliesNot(const char* from,
189
144
                                        const char* to) {
190
144
  auto it = options_.find(to);
191
144
  CHECK_NE(it, options_.end());
192
144
  CHECK_EQ(it->second.type, kBoolean);
193
144
  implications_.emplace(
194
144
      from, Implication{it->second.type, to, it->second.field, false});
195
144
}
node::options_parser::OptionsParser<node::PerIsolateOptions>::ImpliesNot(char const*, char const*)
Line
Count
Source
189
72
                                        const char* to) {
190
72
  auto it = options_.find(to);
191
72
  CHECK_NE(it, options_.end());
192
72
  CHECK_EQ(it->second.type, kBoolean);
193
72
  implications_.emplace(
194
72
      from, Implication{it->second.type, to, it->second.field, false});
195
72
}
node::options_parser::OptionsParser<node::PerProcessOptions>::ImpliesNot(char const*, char const*)
Line
Count
Source
189
72
                                        const char* to) {
190
72
  auto it = options_.find(to);
191
72
  CHECK_NE(it, options_.end());
192
72
  CHECK_EQ(it->second.type, kBoolean);
193
72
  implications_.emplace(
194
72
      from, Implication{it->second.type, to, it->second.field, false});
195
72
}
196
197
template <typename Options>
198
template <typename OriginalField, typename ChildOptions>
199
auto OptionsParser<Options>::Convert(
200
    std::shared_ptr<OriginalField> original,
201
26.3k
    ChildOptions* (Options::* get_child)()) {
202
  // If we have a field on ChildOptions, and we want to access it from an
203
  // Options instance, we call get_child() on the original Options and then
204
  // access it, i.e. this class implements a kind of function chaining.
205
26.3k
  struct AdaptedField : BaseOptionField {
206
26.3k
    void* LookupImpl(Options* options) const override {
207
10.1k
      return original->LookupImpl((options->*get_child)());
208
10.1k
    }
node::options_parser::OptionsParser<node::EnvironmentOptions>::Convert<node::options_parser::OptionsParser<node::DebugOptions>::BaseOptionField, node::DebugOptions>(std::__1::shared_ptr<node::options_parser::OptionsParser<node::DebugOptions>::BaseOptionField>, node::DebugOptions* (node::EnvironmentOptions::*)())::AdaptedField::LookupImpl(node::EnvironmentOptions*) const
Line
Count
Source
206
280
    void* LookupImpl(Options* options) const override {
207
280
      return original->LookupImpl((options->*get_child)());
208
280
    }
node::options_parser::OptionsParser<node::PerIsolateOptions>::Convert<node::options_parser::OptionsParser<node::EnvironmentOptions>::BaseOptionField, node::EnvironmentOptions>(std::__1::shared_ptr<node::options_parser::OptionsParser<node::EnvironmentOptions>::BaseOptionField>, node::EnvironmentOptions* (node::PerIsolateOptions::*)())::AdaptedField::LookupImpl(node::PerIsolateOptions*) const
Line
Count
Source
206
4.79k
    void* LookupImpl(Options* options) const override {
207
4.79k
      return original->LookupImpl((options->*get_child)());
208
4.79k
    }
node::options_parser::OptionsParser<node::PerProcessOptions>::Convert<node::options_parser::OptionsParser<node::PerIsolateOptions>::BaseOptionField, node::PerIsolateOptions>(std::__1::shared_ptr<node::options_parser::OptionsParser<node::PerIsolateOptions>::BaseOptionField>, node::PerIsolateOptions* (node::PerProcessOptions::*)())::AdaptedField::LookupImpl(node::PerProcessOptions*) const
Line
Count
Source
206
5.11k
    void* LookupImpl(Options* options) const override {
207
5.11k
      return original->LookupImpl((options->*get_child)());
208
5.11k
    }
209
210
26.3k
    AdaptedField(
211
26.3k
        std::shared_ptr<OriginalField> original,
212
26.3k
        ChildOptions* (Options::* get_child)())
213
26.3k
          : original(original), get_child(get_child) {}
node::options_parser::OptionsParser<node::EnvironmentOptions>::Convert<node::options_parser::OptionsParser<node::DebugOptions>::BaseOptionField, node::DebugOptions>(std::__1::shared_ptr<node::options_parser::OptionsParser<node::DebugOptions>::BaseOptionField>, node::DebugOptions* (node::EnvironmentOptions::*)())::AdaptedField::AdaptedField(std::__1::shared_ptr<node::options_parser::OptionsParser<node::DebugOptions>::BaseOptionField>, node::DebugOptions* (node::EnvironmentOptions::*)())
Line
Count
Source
213
792
          : original(original), get_child(get_child) {}
node::options_parser::OptionsParser<node::PerIsolateOptions>::Convert<node::options_parser::OptionsParser<node::EnvironmentOptions>::BaseOptionField, node::EnvironmentOptions>(std::__1::shared_ptr<node::options_parser::OptionsParser<node::EnvironmentOptions>::BaseOptionField>, node::EnvironmentOptions* (node::PerIsolateOptions::*)())::AdaptedField::AdaptedField(std::__1::shared_ptr<node::options_parser::OptionsParser<node::EnvironmentOptions>::BaseOptionField>, node::EnvironmentOptions* (node::PerIsolateOptions::*)())
Line
Count
Source
213
11.8k
          : original(original), get_child(get_child) {}
node::options_parser::OptionsParser<node::PerProcessOptions>::Convert<node::options_parser::OptionsParser<node::PerIsolateOptions>::BaseOptionField, node::PerIsolateOptions>(std::__1::shared_ptr<node::options_parser::OptionsParser<node::PerIsolateOptions>::BaseOptionField>, node::PerIsolateOptions* (node::PerProcessOptions::*)())::AdaptedField::AdaptedField(std::__1::shared_ptr<node::options_parser::OptionsParser<node::PerIsolateOptions>::BaseOptionField>, node::PerIsolateOptions* (node::PerProcessOptions::*)())
Line
Count
Source
213
13.7k
          : original(original), get_child(get_child) {}
214
215
26.3k
    std::shared_ptr<OriginalField> original;
216
26.3k
    ChildOptions* (Options::* get_child)();
217
26.3k
  };
218
219
26.3k
  return std::shared_ptr<BaseOptionField>(
220
26.3k
      new AdaptedField(original, get_child));
221
26.3k
}
auto node::options_parser::OptionsParser<node::EnvironmentOptions>::Convert<node::options_parser::OptionsParser<node::DebugOptions>::BaseOptionField, node::DebugOptions>(std::__1::shared_ptr<node::options_parser::OptionsParser<node::DebugOptions>::BaseOptionField>, node::DebugOptions* (node::EnvironmentOptions::*)())
Line
Count
Source
201
792
    ChildOptions* (Options::* get_child)()) {
202
  // If we have a field on ChildOptions, and we want to access it from an
203
  // Options instance, we call get_child() on the original Options and then
204
  // access it, i.e. this class implements a kind of function chaining.
205
792
  struct AdaptedField : BaseOptionField {
206
792
    void* LookupImpl(Options* options) const override {
207
792
      return original->LookupImpl((options->*get_child)());
208
792
    }
209
210
792
    AdaptedField(
211
792
        std::shared_ptr<OriginalField> original,
212
792
        ChildOptions* (Options::* get_child)())
213
792
          : original(original), get_child(get_child) {}
214
215
792
    std::shared_ptr<OriginalField> original;
216
792
    ChildOptions* (Options::* get_child)();
217
792
  };
218
219
792
  return std::shared_ptr<BaseOptionField>(
220
792
      new AdaptedField(original, get_child));
221
792
}
auto node::options_parser::OptionsParser<node::PerIsolateOptions>::Convert<node::options_parser::OptionsParser<node::EnvironmentOptions>::BaseOptionField, node::EnvironmentOptions>(std::__1::shared_ptr<node::options_parser::OptionsParser<node::EnvironmentOptions>::BaseOptionField>, node::EnvironmentOptions* (node::PerIsolateOptions::*)())
Line
Count
Source
201
11.8k
    ChildOptions* (Options::* get_child)()) {
202
  // If we have a field on ChildOptions, and we want to access it from an
203
  // Options instance, we call get_child() on the original Options and then
204
  // access it, i.e. this class implements a kind of function chaining.
205
11.8k
  struct AdaptedField : BaseOptionField {
206
11.8k
    void* LookupImpl(Options* options) const override {
207
11.8k
      return original->LookupImpl((options->*get_child)());
208
11.8k
    }
209
210
11.8k
    AdaptedField(
211
11.8k
        std::shared_ptr<OriginalField> original,
212
11.8k
        ChildOptions* (Options::* get_child)())
213
11.8k
          : original(original), get_child(get_child) {}
214
215
11.8k
    std::shared_ptr<OriginalField> original;
216
11.8k
    ChildOptions* (Options::* get_child)();
217
11.8k
  };
218
219
11.8k
  return std::shared_ptr<BaseOptionField>(
220
11.8k
      new AdaptedField(original, get_child));
221
11.8k
}
auto node::options_parser::OptionsParser<node::PerProcessOptions>::Convert<node::options_parser::OptionsParser<node::PerIsolateOptions>::BaseOptionField, node::PerIsolateOptions>(std::__1::shared_ptr<node::options_parser::OptionsParser<node::PerIsolateOptions>::BaseOptionField>, node::PerIsolateOptions* (node::PerProcessOptions::*)())
Line
Count
Source
201
13.7k
    ChildOptions* (Options::* get_child)()) {
202
  // If we have a field on ChildOptions, and we want to access it from an
203
  // Options instance, we call get_child() on the original Options and then
204
  // access it, i.e. this class implements a kind of function chaining.
205
13.7k
  struct AdaptedField : BaseOptionField {
206
13.7k
    void* LookupImpl(Options* options) const override {
207
13.7k
      return original->LookupImpl((options->*get_child)());
208
13.7k
    }
209
210
13.7k
    AdaptedField(
211
13.7k
        std::shared_ptr<OriginalField> original,
212
13.7k
        ChildOptions* (Options::* get_child)())
213
13.7k
          : original(original), get_child(get_child) {}
214
215
13.7k
    std::shared_ptr<OriginalField> original;
216
13.7k
    ChildOptions* (Options::* get_child)();
217
13.7k
  };
218
219
13.7k
  return std::shared_ptr<BaseOptionField>(
220
13.7k
      new AdaptedField(original, get_child));
221
13.7k
}
222
template <typename Options>
223
template <typename ChildOptions>
224
auto OptionsParser<Options>::Convert(
225
    typename OptionsParser<ChildOptions>::OptionInfo original,
226
24.1k
    ChildOptions* (Options::* get_child)()) {
227
24.1k
  return OptionInfo{original.type,
228
24.1k
                    Convert(original.field, get_child),
229
24.1k
                    original.env_setting,
230
24.1k
                    original.help_text,
231
24.1k
                    original.default_is_true,
232
24.1k
                    original.namespace_id};
233
24.1k
}
auto node::options_parser::OptionsParser<node::EnvironmentOptions>::Convert<node::DebugOptions>(node::options_parser::OptionsParser<node::DebugOptions>::OptionInfo, node::DebugOptions* (node::EnvironmentOptions::*)())
Line
Count
Source
226
576
    ChildOptions* (Options::* get_child)()) {
227
576
  return OptionInfo{original.type,
228
576
                    Convert(original.field, get_child),
229
576
                    original.env_setting,
230
576
                    original.help_text,
231
576
                    original.default_is_true,
232
576
                    original.namespace_id};
233
576
}
auto node::options_parser::OptionsParser<node::PerIsolateOptions>::Convert<node::EnvironmentOptions>(node::options_parser::OptionsParser<node::EnvironmentOptions>::OptionInfo, node::EnvironmentOptions* (node::PerIsolateOptions::*)())
Line
Count
Source
226
11.0k
    ChildOptions* (Options::* get_child)()) {
227
11.0k
  return OptionInfo{original.type,
228
11.0k
                    Convert(original.field, get_child),
229
11.0k
                    original.env_setting,
230
11.0k
                    original.help_text,
231
11.0k
                    original.default_is_true,
232
11.0k
                    original.namespace_id};
233
11.0k
}
auto node::options_parser::OptionsParser<node::PerProcessOptions>::Convert<node::PerIsolateOptions>(node::options_parser::OptionsParser<node::PerIsolateOptions>::OptionInfo, node::PerIsolateOptions* (node::PerProcessOptions::*)())
Line
Count
Source
226
12.6k
    ChildOptions* (Options::* get_child)()) {
227
12.6k
  return OptionInfo{original.type,
228
12.6k
                    Convert(original.field, get_child),
229
12.6k
                    original.env_setting,
230
12.6k
                    original.help_text,
231
12.6k
                    original.default_is_true,
232
12.6k
                    original.namespace_id};
233
12.6k
}
234
235
template <typename Options>
236
template <typename ChildOptions>
237
auto OptionsParser<Options>::Convert(
238
    typename OptionsParser<ChildOptions>::Implication original,
239
2.16k
    ChildOptions* (Options::* get_child)()) {
240
2.16k
  return Implication{
241
2.16k
      original.type,
242
2.16k
      original.name,
243
2.16k
      Convert(original.target_field, get_child),
244
2.16k
      original.target_value,
245
2.16k
  };
246
2.16k
}
auto node::options_parser::OptionsParser<node::EnvironmentOptions>::Convert<node::DebugOptions>(node::options_parser::OptionsParser<node::DebugOptions>::Implication, node::DebugOptions* (node::EnvironmentOptions::*)())
Line
Count
Source
239
216
    ChildOptions* (Options::* get_child)()) {
240
216
  return Implication{
241
216
      original.type,
242
216
      original.name,
243
216
      Convert(original.target_field, get_child),
244
216
      original.target_value,
245
216
  };
246
216
}
auto node::options_parser::OptionsParser<node::PerIsolateOptions>::Convert<node::EnvironmentOptions>(node::options_parser::OptionsParser<node::EnvironmentOptions>::Implication, node::EnvironmentOptions* (node::PerIsolateOptions::*)())
Line
Count
Source
239
792
    ChildOptions* (Options::* get_child)()) {
240
792
  return Implication{
241
792
      original.type,
242
792
      original.name,
243
792
      Convert(original.target_field, get_child),
244
792
      original.target_value,
245
792
  };
246
792
}
auto node::options_parser::OptionsParser<node::PerProcessOptions>::Convert<node::PerIsolateOptions>(node::options_parser::OptionsParser<node::PerIsolateOptions>::Implication, node::PerIsolateOptions* (node::PerProcessOptions::*)())
Line
Count
Source
239
1.15k
    ChildOptions* (Options::* get_child)()) {
240
1.15k
  return Implication{
241
1.15k
      original.type,
242
1.15k
      original.name,
243
1.15k
      Convert(original.target_field, get_child),
244
1.15k
      original.target_value,
245
1.15k
  };
246
1.15k
}
247
248
template <typename Options>
249
template <typename ChildOptions>
250
void OptionsParser<Options>::Insert(
251
    const OptionsParser<ChildOptions>& child_options_parser,
252
216
    ChildOptions* (Options::* get_child)()) {
253
216
  aliases_.insert(std::begin(child_options_parser.aliases_),
254
216
                  std::end(child_options_parser.aliases_));
255
256
216
  for (const auto& pair : child_options_parser.options_)
257
24.1k
    options_.emplace(pair.first, Convert(pair.second, get_child));
258
259
216
  for (const auto& pair : child_options_parser.implications_)
260
2.16k
    implications_.emplace(pair.first, Convert(pair.second, get_child));
261
216
}
void node::options_parser::OptionsParser<node::EnvironmentOptions>::Insert<node::DebugOptions>(node::options_parser::OptionsParser<node::DebugOptions> const&, node::DebugOptions* (node::EnvironmentOptions::*)())
Line
Count
Source
252
72
    ChildOptions* (Options::* get_child)()) {
253
72
  aliases_.insert(std::begin(child_options_parser.aliases_),
254
72
                  std::end(child_options_parser.aliases_));
255
256
72
  for (const auto& pair : child_options_parser.options_)
257
576
    options_.emplace(pair.first, Convert(pair.second, get_child));
258
259
72
  for (const auto& pair : child_options_parser.implications_)
260
216
    implications_.emplace(pair.first, Convert(pair.second, get_child));
261
72
}
void node::options_parser::OptionsParser<node::PerIsolateOptions>::Insert<node::EnvironmentOptions>(node::options_parser::OptionsParser<node::EnvironmentOptions> const&, node::EnvironmentOptions* (node::PerIsolateOptions::*)())
Line
Count
Source
252
72
    ChildOptions* (Options::* get_child)()) {
253
72
  aliases_.insert(std::begin(child_options_parser.aliases_),
254
72
                  std::end(child_options_parser.aliases_));
255
256
72
  for (const auto& pair : child_options_parser.options_)
257
11.0k
    options_.emplace(pair.first, Convert(pair.second, get_child));
258
259
72
  for (const auto& pair : child_options_parser.implications_)
260
792
    implications_.emplace(pair.first, Convert(pair.second, get_child));
261
72
}
void node::options_parser::OptionsParser<node::PerProcessOptions>::Insert<node::PerIsolateOptions>(node::options_parser::OptionsParser<node::PerIsolateOptions> const&, node::PerIsolateOptions* (node::PerProcessOptions::*)())
Line
Count
Source
252
72
    ChildOptions* (Options::* get_child)()) {
253
72
  aliases_.insert(std::begin(child_options_parser.aliases_),
254
72
                  std::end(child_options_parser.aliases_));
255
256
72
  for (const auto& pair : child_options_parser.options_)
257
12.6k
    options_.emplace(pair.first, Convert(pair.second, get_child));
258
259
72
  for (const auto& pair : child_options_parser.implications_)
260
1.15k
    implications_.emplace(pair.first, Convert(pair.second, get_child));
261
72
}
262
263
0
inline std::string NotAllowedInEnvErr(const std::string& arg) {
264
0
  return arg + " is not allowed in NODE_OPTIONS";
265
0
}
266
267
0
inline std::string RequiresArgumentErr(const std::string& arg) {
268
0
  return arg + " requires an argument";
269
0
}
270
271
0
inline std::string NegationImpliesBooleanError(const std::string& arg) {
272
0
  return arg + " is an invalid negation because it is not a boolean option";
273
0
}
274
275
// We store some of the basic information around a single Parse call inside
276
// this struct, to separate storage of command line arguments and their
277
// handling. In particular, this makes it easier to introduce 'synthetic'
278
// arguments that get inserted by expanding option aliases.
279
struct ArgsInfo {
280
  // Generally, the idea here is that the first entry in `*underlying` stores
281
  // the "0th" argument (the program name), then `synthetic_args` are inserted,
282
  // followed by the remainder of `*underlying`.
283
  std::vector<std::string>* underlying;
284
  std::vector<std::string> synthetic_args;
285
286
  std::vector<std::string>* exec_args;
287
288
  ArgsInfo(std::vector<std::string>* args,
289
           std::vector<std::string>* exec_args)
290
70
    : underlying(args), exec_args(exec_args) {}
291
292
70
  size_t remaining() const {
293
    // -1 to account for the program name.
294
70
    return underlying->size() - 1 + synthetic_args.size();
295
70
  }
296
297
70
  bool empty() const { return remaining() == 0; }
298
70
  const std::string& program_name() const { return underlying->at(0); }
299
300
0
  std::string& first() {
301
0
    return synthetic_args.empty() ? underlying->at(1) : synthetic_args.front();
302
0
  }
303
304
0
  std::string pop_first() {
305
0
    std::string ret = std::move(first());
306
0
    if (synthetic_args.empty()) {
307
      // Only push arguments to `exec_args` that were also originally passed
308
      // on the command line (i.e. not generated through alias expansion).
309
      // '--' is a special case here since its purpose is to end `exec_argv`,
310
      // which is why we do not include it.
311
0
      if (exec_args != nullptr && ret != "--")
312
0
        exec_args->push_back(ret);
313
0
      underlying->erase(underlying->begin() + 1);
314
0
    } else {
315
0
      synthetic_args.erase(synthetic_args.begin());
316
0
    }
317
0
    return ret;
318
0
  }
319
};
320
321
template <typename Options>
322
void OptionsParser<Options>::Parse(
323
    std::vector<std::string>* const orig_args,
324
    std::vector<std::string>* const exec_args,
325
    std::vector<std::string>* const v8_args,
326
    Options* const options,
327
    OptionEnvvarSettings required_env_settings,
328
70
    std::vector<std::string>* const errors) const {
329
70
  ArgsInfo args(orig_args, exec_args);
330
331
  // The first entry is the process name. Make sure it ends up in the V8 argv,
332
  // since V8::SetFlagsFromCommandLine() expects that to hold true for that
333
  // array as well.
334
70
  if (v8_args->empty())
335
70
    v8_args->push_back(args.program_name());
336
337
70
  while (!args.empty() && errors->empty()) {
338
0
    if (args.first().size() <= 1 || args.first()[0] != '-') break;
339
340
    // We know that we're either going to consume this
341
    // argument or fail completely.
342
0
    const std::string arg = args.pop_first();
343
344
0
    if (arg == "--") {
345
0
      if (required_env_settings == kAllowedInEnvvar)
346
0
        errors->push_back(NotAllowedInEnvErr("--"));
347
0
      break;
348
0
    }
349
350
    // Only allow --foo=bar notation for options starting with double dashes.
351
    // (E.g. -e=a is not allowed as shorthand for --eval=a, which would
352
    // otherwise be the result of alias expansion.)
353
0
    const std::string::size_type equals_index =
354
0
        arg[0] == '-' && arg[1] == '-' ? arg.find('=') : std::string::npos;
355
0
    std::string name =
356
0
      equals_index == std::string::npos ? arg : arg.substr(0, equals_index);
357
358
    // Store the 'original name' of the argument. This name differs from
359
    // 'name' in that it contains a possible '=' sign and is not affected
360
    // by alias expansion.
361
0
    std::string original_name = name;
362
0
    if (equals_index != std::string::npos)
363
0
      original_name += '=';
364
365
0
    auto missing_argument = [&]() {
366
0
      errors->push_back(RequiresArgumentErr(original_name));
367
0
    };
Unexecuted instantiation: node::options_parser::OptionsParser<node::DebugOptions>::Parse(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*, node::DebugOptions*, node::OptionEnvvarSettings, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*) const::{lambda()#1}::operator()() const
Unexecuted instantiation: node::options_parser::OptionsParser<node::PerIsolateOptions>::Parse(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*, node::PerIsolateOptions*, node::OptionEnvvarSettings, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*) const::{lambda()#1}::operator()() const
Unexecuted instantiation: node::options_parser::OptionsParser<node::PerProcessOptions>::Parse(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*, node::PerProcessOptions*, node::OptionEnvvarSettings, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*) const::{lambda()#1}::operator()() const
368
369
    // Normalize by replacing `_` with `-` in options.
370
0
    for (std::string::size_type i = 2; i < name.size(); ++i) {
371
0
      if (name[i] == '_')
372
0
        name[i] = '-';
373
0
    }
374
375
    // Convert --no-foo to --foo and keep in mind that we're negating.
376
0
    bool is_negation = false;
377
0
    if (name.find("--no-") == 0) {
378
0
      name.erase(2, 3);  // remove no-
379
0
      is_negation = true;
380
0
    }
381
382
0
    {
383
0
      auto it = aliases_.end();
384
      // Expand aliases:
385
      // - If `name` can be found in `aliases_`.
386
      // - If `name` + '=' can be found in `aliases_`.
387
      // - If `name` + " <arg>" can be found in `aliases_`, and we have
388
      //   a subsequent argument that does not start with '-' itself.
389
0
      while ((it = aliases_.find(name)) != aliases_.end() ||
390
0
             (equals_index != std::string::npos &&
391
0
              (it = aliases_.find(name + '=')) != aliases_.end()) ||
392
0
             (!args.empty() &&
393
0
                 !args.first().empty() &&
394
0
                 args.first()[0] != '-' &&
395
0
              (it = aliases_.find(name + " <arg>")) != aliases_.end())) {
396
0
        const std::string prev_name = std::move(name);
397
0
        const std::vector<std::string>& expansion = it->second;
398
399
        // Use the first entry in the expansion as the new 'name'.
400
0
        name = expansion.front();
401
402
0
        if (expansion.size() > 1) {
403
          // The other arguments, if any, are going to be handled later.
404
0
          args.synthetic_args.insert(
405
0
              args.synthetic_args.begin(),
406
0
              expansion.begin() + 1,
407
0
              expansion.end());
408
0
        }
409
410
0
        if (name == prev_name) break;
411
0
      }
412
0
    }
413
414
0
    auto it = options_.find(name);
415
416
0
    if ((it == options_.end() ||
417
0
         it->second.env_setting == kDisallowedInEnvvar) &&
418
0
        required_env_settings == kAllowedInEnvvar) {
419
0
      errors->push_back(NotAllowedInEnvErr(original_name));
420
0
      break;
421
0
    }
422
423
0
    {
424
0
      std::string implied_name = name;
425
0
      if (is_negation) {
426
        // Implications for negated options are defined with "--no-".
427
0
        implied_name.insert(2, "no-");
428
0
      }
429
0
      auto [f, l] = implications_.equal_range(implied_name);
430
0
      std::ranges::for_each(std::ranges::subrange(f, l) | std::views::values,
431
0
                            [&](const auto& value) {
432
0
                              if (value.type == kV8Option) {
433
0
                                v8_args->push_back(value.name);
434
0
                              } else {
435
0
                                *value.target_field->template Lookup<bool>(
436
0
                                    options) = value.target_value;
437
0
                              }
438
0
                            });
Unexecuted instantiation: auto node::options_parser::OptionsParser<node::DebugOptions>::Parse(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*, node::DebugOptions*, node::OptionEnvvarSettings, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*) const::{lambda(auto:1 const&)#1}::operator()<node::options_parser::OptionsParser<node::DebugOptions>::Implication>(node::options_parser::OptionsParser<node::DebugOptions>::Implication const&) const
Unexecuted instantiation: auto node::options_parser::OptionsParser<node::PerIsolateOptions>::Parse(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*, node::PerIsolateOptions*, node::OptionEnvvarSettings, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*) const::{lambda(auto:1 const&)#1}::operator()<node::options_parser::OptionsParser<node::PerIsolateOptions>::Implication>(node::options_parser::OptionsParser<node::PerIsolateOptions>::Implication const&) const
Unexecuted instantiation: auto node::options_parser::OptionsParser<node::PerProcessOptions>::Parse(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*, node::PerProcessOptions*, node::OptionEnvvarSettings, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*) const::{lambda(auto:1 const&)#1}::operator()<node::options_parser::OptionsParser<node::PerProcessOptions>::Implication>(node::options_parser::OptionsParser<node::PerProcessOptions>::Implication const&) const
439
0
    }
440
441
0
    if (it == options_.end()) {
442
0
      v8_args->push_back(arg);
443
0
      continue;
444
0
    }
445
446
0
    const OptionInfo& info = it->second;
447
448
    // Some V8 options can be negated and they are validated by V8 later.
449
0
    if (is_negation && info.type != kBoolean && info.type != kV8Option) {
450
0
      errors->push_back(NegationImpliesBooleanError(arg));
451
0
      break;
452
0
    }
453
454
0
    std::string value;
455
0
    if (info.type != kBoolean && info.type != kNoOp && info.type != kV8Option) {
456
0
      if (equals_index != std::string::npos) {
457
0
        value = arg.substr(equals_index + 1);
458
0
        if (value.empty()) {
459
0
          missing_argument();
460
0
          break;
461
0
        }
462
0
      } else {
463
0
        if (args.empty()) {
464
0
          missing_argument();
465
0
          break;
466
0
        }
467
468
0
        value = args.pop_first();
469
470
0
        if (!value.empty() && value[0] == '-') {
471
0
          missing_argument();
472
0
          break;
473
0
        } else {
474
0
          if (!value.empty() && value[0] == '\\' && value[1] == '-')
475
0
            value = value.substr(1);  // Treat \- as escaping an -.
476
0
        }
477
0
      }
478
0
    }
479
480
0
    switch (info.type) {
481
0
      case kBoolean:
482
0
        *Lookup<bool>(info.field, options) = !is_negation;
483
0
        break;
484
0
      case kInteger: {
485
        // Special case to pass --stack-trace-limit down to V8.
486
0
        if (name == "--stack-trace-limit") {
487
0
          v8_args->push_back(arg);
488
0
        }
489
0
        *Lookup<int64_t>(info.field, options) = std::atoll(value.c_str());
490
0
        break;
491
0
      }
492
0
      case kUInteger:
493
0
        *Lookup<uint64_t>(info.field, options) =
494
0
            std::strtoull(value.c_str(), nullptr, 10);
495
0
        break;
496
0
      case kString:
497
0
        *Lookup<std::string>(info.field, options) = value;
498
0
        break;
499
0
      case kStringList:
500
0
        Lookup<std::vector<std::string>>(info.field, options)
501
0
            ->emplace_back(std::move(value));
502
0
        break;
503
0
      case kHostPort:
504
0
        Lookup<HostPort>(info.field, options)
505
0
            ->Update(SplitHostPort(value, errors));
506
0
        break;
507
0
      case kNoOp:
508
0
        break;
509
0
      case kV8Option:
510
0
        v8_args->push_back(arg);
511
0
        break;
512
0
      default:
513
0
        UNREACHABLE();
514
0
    }
515
0
  }
516
70
  options->CheckOptions(errors, orig_args);
517
70
}
Unexecuted instantiation: node::options_parser::OptionsParser<node::DebugOptions>::Parse(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*, node::DebugOptions*, node::OptionEnvvarSettings, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*) const
Unexecuted instantiation: node::options_parser::OptionsParser<node::PerIsolateOptions>::Parse(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*, node::PerIsolateOptions*, node::OptionEnvvarSettings, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*) const
node::options_parser::OptionsParser<node::PerProcessOptions>::Parse(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*, node::PerProcessOptions*, node::OptionEnvvarSettings, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*) const
Line
Count
Source
328
70
    std::vector<std::string>* const errors) const {
329
70
  ArgsInfo args(orig_args, exec_args);
330
331
  // The first entry is the process name. Make sure it ends up in the V8 argv,
332
  // since V8::SetFlagsFromCommandLine() expects that to hold true for that
333
  // array as well.
334
70
  if (v8_args->empty())
335
70
    v8_args->push_back(args.program_name());
336
337
70
  while (!args.empty() && errors->empty()) {
338
0
    if (args.first().size() <= 1 || args.first()[0] != '-') break;
339
340
    // We know that we're either going to consume this
341
    // argument or fail completely.
342
0
    const std::string arg = args.pop_first();
343
344
0
    if (arg == "--") {
345
0
      if (required_env_settings == kAllowedInEnvvar)
346
0
        errors->push_back(NotAllowedInEnvErr("--"));
347
0
      break;
348
0
    }
349
350
    // Only allow --foo=bar notation for options starting with double dashes.
351
    // (E.g. -e=a is not allowed as shorthand for --eval=a, which would
352
    // otherwise be the result of alias expansion.)
353
0
    const std::string::size_type equals_index =
354
0
        arg[0] == '-' && arg[1] == '-' ? arg.find('=') : std::string::npos;
355
0
    std::string name =
356
0
      equals_index == std::string::npos ? arg : arg.substr(0, equals_index);
357
358
    // Store the 'original name' of the argument. This name differs from
359
    // 'name' in that it contains a possible '=' sign and is not affected
360
    // by alias expansion.
361
0
    std::string original_name = name;
362
0
    if (equals_index != std::string::npos)
363
0
      original_name += '=';
364
365
0
    auto missing_argument = [&]() {
366
0
      errors->push_back(RequiresArgumentErr(original_name));
367
0
    };
368
369
    // Normalize by replacing `_` with `-` in options.
370
0
    for (std::string::size_type i = 2; i < name.size(); ++i) {
371
0
      if (name[i] == '_')
372
0
        name[i] = '-';
373
0
    }
374
375
    // Convert --no-foo to --foo and keep in mind that we're negating.
376
0
    bool is_negation = false;
377
0
    if (name.find("--no-") == 0) {
378
0
      name.erase(2, 3);  // remove no-
379
0
      is_negation = true;
380
0
    }
381
382
0
    {
383
0
      auto it = aliases_.end();
384
      // Expand aliases:
385
      // - If `name` can be found in `aliases_`.
386
      // - If `name` + '=' can be found in `aliases_`.
387
      // - If `name` + " <arg>" can be found in `aliases_`, and we have
388
      //   a subsequent argument that does not start with '-' itself.
389
0
      while ((it = aliases_.find(name)) != aliases_.end() ||
390
0
             (equals_index != std::string::npos &&
391
0
              (it = aliases_.find(name + '=')) != aliases_.end()) ||
392
0
             (!args.empty() &&
393
0
                 !args.first().empty() &&
394
0
                 args.first()[0] != '-' &&
395
0
              (it = aliases_.find(name + " <arg>")) != aliases_.end())) {
396
0
        const std::string prev_name = std::move(name);
397
0
        const std::vector<std::string>& expansion = it->second;
398
399
        // Use the first entry in the expansion as the new 'name'.
400
0
        name = expansion.front();
401
402
0
        if (expansion.size() > 1) {
403
          // The other arguments, if any, are going to be handled later.
404
0
          args.synthetic_args.insert(
405
0
              args.synthetic_args.begin(),
406
0
              expansion.begin() + 1,
407
0
              expansion.end());
408
0
        }
409
410
0
        if (name == prev_name) break;
411
0
      }
412
0
    }
413
414
0
    auto it = options_.find(name);
415
416
0
    if ((it == options_.end() ||
417
0
         it->second.env_setting == kDisallowedInEnvvar) &&
418
0
        required_env_settings == kAllowedInEnvvar) {
419
0
      errors->push_back(NotAllowedInEnvErr(original_name));
420
0
      break;
421
0
    }
422
423
0
    {
424
0
      std::string implied_name = name;
425
0
      if (is_negation) {
426
        // Implications for negated options are defined with "--no-".
427
0
        implied_name.insert(2, "no-");
428
0
      }
429
0
      auto [f, l] = implications_.equal_range(implied_name);
430
0
      std::ranges::for_each(std::ranges::subrange(f, l) | std::views::values,
431
0
                            [&](const auto& value) {
432
0
                              if (value.type == kV8Option) {
433
0
                                v8_args->push_back(value.name);
434
0
                              } else {
435
0
                                *value.target_field->template Lookup<bool>(
436
0
                                    options) = value.target_value;
437
0
                              }
438
0
                            });
439
0
    }
440
441
0
    if (it == options_.end()) {
442
0
      v8_args->push_back(arg);
443
0
      continue;
444
0
    }
445
446
0
    const OptionInfo& info = it->second;
447
448
    // Some V8 options can be negated and they are validated by V8 later.
449
0
    if (is_negation && info.type != kBoolean && info.type != kV8Option) {
450
0
      errors->push_back(NegationImpliesBooleanError(arg));
451
0
      break;
452
0
    }
453
454
0
    std::string value;
455
0
    if (info.type != kBoolean && info.type != kNoOp && info.type != kV8Option) {
456
0
      if (equals_index != std::string::npos) {
457
0
        value = arg.substr(equals_index + 1);
458
0
        if (value.empty()) {
459
0
          missing_argument();
460
0
          break;
461
0
        }
462
0
      } else {
463
0
        if (args.empty()) {
464
0
          missing_argument();
465
0
          break;
466
0
        }
467
468
0
        value = args.pop_first();
469
470
0
        if (!value.empty() && value[0] == '-') {
471
0
          missing_argument();
472
0
          break;
473
0
        } else {
474
0
          if (!value.empty() && value[0] == '\\' && value[1] == '-')
475
0
            value = value.substr(1);  // Treat \- as escaping an -.
476
0
        }
477
0
      }
478
0
    }
479
480
0
    switch (info.type) {
481
0
      case kBoolean:
482
0
        *Lookup<bool>(info.field, options) = !is_negation;
483
0
        break;
484
0
      case kInteger: {
485
        // Special case to pass --stack-trace-limit down to V8.
486
0
        if (name == "--stack-trace-limit") {
487
0
          v8_args->push_back(arg);
488
0
        }
489
0
        *Lookup<int64_t>(info.field, options) = std::atoll(value.c_str());
490
0
        break;
491
0
      }
492
0
      case kUInteger:
493
0
        *Lookup<uint64_t>(info.field, options) =
494
0
            std::strtoull(value.c_str(), nullptr, 10);
495
0
        break;
496
0
      case kString:
497
0
        *Lookup<std::string>(info.field, options) = value;
498
0
        break;
499
0
      case kStringList:
500
0
        Lookup<std::vector<std::string>>(info.field, options)
501
0
            ->emplace_back(std::move(value));
502
0
        break;
503
0
      case kHostPort:
504
0
        Lookup<HostPort>(info.field, options)
505
0
            ->Update(SplitHostPort(value, errors));
506
0
        break;
507
0
      case kNoOp:
508
0
        break;
509
0
      case kV8Option:
510
0
        v8_args->push_back(arg);
511
0
        break;
512
0
      default:
513
0
        UNREACHABLE();
514
0
    }
515
0
  }
516
70
  options->CheckOptions(errors, orig_args);
517
70
}
518
519
}  // namespace options_parser
520
}  // namespace node
521
522
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
523
524
#endif  // SRC_NODE_OPTIONS_INL_H_