GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/node_options.cc Lines: 215 256 84.0 %
Date: 2019-02-01 22:03:38 Branches: 94 204 46.1 %

Line Branch Exec Source
1
#include <errno.h>
2
#include "env-inl.h"
3
#include "node_binding.h"
4
#include "node_options-inl.h"
5
6
using v8::Boolean;
7
using v8::Context;
8
using v8::FunctionCallbackInfo;
9
using v8::Integer;
10
using v8::Isolate;
11
using v8::Local;
12
using v8::Map;
13
using v8::Number;
14
using v8::Object;
15
using v8::String;
16
using v8::Undefined;
17
using v8::Value;
18
19
namespace node {
20
21
namespace per_process {
22
164
Mutex cli_options_mutex;
23
164
std::shared_ptr<PerProcessOptions> cli_options{new PerProcessOptions()};
24
}  // namespace per_process
25
26
230
void DebugOptions::CheckOptions(std::vector<std::string>* errors) {
27
#if !NODE_USE_V8_PLATFORM
28
  if (inspector_enabled) {
29
    errors->push_back("Inspector is not available when Node is compiled "
30
                      "--without-v8-platform");
31
  }
32
#endif
33
34

230
  if (deprecated_debug && !inspector_enabled) {
35
    errors->push_back("[DEP0062]: `node --debug` and `node --debug-brk` "
36
                      "are invalid. Please use `node --inspect` or "
37
                      "`node --inspect-brk` instead.");
38
  }
39
40

230
  if (deprecated_debug && inspector_enabled && break_first_line) {
41
    errors->push_back("[DEP0062]: `node --inspect --debug-brk` is deprecated. "
42
                      "Please use `node --inspect-brk` instead.");
43
  }
44
230
}
45
46
230
void PerProcessOptions::CheckOptions(std::vector<std::string>* errors) {
47
#if HAVE_OPENSSL
48

230
  if (use_openssl_ca && use_bundled_ca) {
49
    errors->push_back("either --use-openssl-ca or --use-bundled-ca can be "
50
                      "used, not both");
51
  }
52
#endif
53
230
  per_isolate->CheckOptions(errors);
54
230
}
55
56
230
void PerIsolateOptions::CheckOptions(std::vector<std::string>* errors) {
57
230
  per_env->CheckOptions(errors);
58
#ifdef NODE_REPORT
59
230
  if (per_env->experimental_report)
60
230
    return;
61
62
230
  if (!report_directory.empty()) {
63
    errors->push_back("--diagnostic-report-directory option is valid only when "
64
                      "--experimental-report is set");
65
  }
66
67
230
  if (!report_filename.empty()) {
68
    errors->push_back("--diagnostic-report-filename option is valid only when "
69
                      "--experimental-report is set");
70
  }
71
72
230
  if (!report_signal.empty()) {
73
    errors->push_back("--diagnostic-report-signal option is valid only when "
74
                      "--experimental-report is set");
75
  }
76
77
230
  if (report_on_fatalerror) {
78
    errors->push_back(
79
        "--diagnostic-report-on-fatalerror option is valid only when "
80
        "--experimental-report is set");
81
  }
82
83
230
  if (report_on_signal) {
84
    errors->push_back("--diagnostic-report-on-signal option is valid only when "
85
                      "--experimental-report is set");
86
  }
87
88
230
  if (report_uncaught_exception) {
89
    errors->push_back(
90
        "--diagnostic-report-uncaught-exception option is valid only when "
91
        "--experimental-report is set");
92
  }
93
94
230
  if (report_verbose) {
95
    errors->push_back("--diagnostic-report-verbose option is valid only when "
96
                      "--experimental-report is set");
97
  }
98
#endif  // NODE_REPORT
99
}
100
101
230
void EnvironmentOptions::CheckOptions(std::vector<std::string>* errors) {
102

230
  if (!userland_loader.empty() && !experimental_modules) {
103
    errors->push_back("--loader requires --experimental-modules be enabled");
104
  }
105
106

230
  if (syntax_check_only && has_eval_string) {
107
    errors->push_back("either --check or --eval can be used, not both");
108
  }
109
110

230
  if (http_parser != "legacy" && http_parser != "llhttp") {
111
    errors->push_back("invalid value for --http-parser");
112
  }
113
114
#if HAVE_INSPECTOR
115
230
  debug_options_.CheckOptions(errors);
116
#endif  // HAVE_INSPECTOR
117
230
}
118
119
namespace options_parser {
120
121
// Explicitly access the singelton instances in their dependancy order.
122
// This was moved here to workaround a compiler bug.
123
// Refs: https://github.com/nodejs/node/issues/25593
124
125
#if HAVE_INSPECTOR
126
164
const DebugOptionsParser DebugOptionsParser::instance;
127
#endif  // HAVE_INSPECTOR
128
129
164
const EnvironmentOptionsParser EnvironmentOptionsParser::instance;
130
131
164
const PerIsolateOptionsParser PerIsolateOptionsParser::instance;
132
133
164
const PerProcessOptionsParser PerProcessOptionsParser::instance;
134
135
// XXX: If you add an option here, please also add it to doc/node.1 and
136
// doc/api/cli.md
137
// TODO(addaleax): Make that unnecessary.
138
139
164
DebugOptionsParser::DebugOptionsParser() {
140
  AddOption("--inspect-port",
141
            "set host:port for inspector",
142
            &DebugOptions::host_port,
143
164
            kAllowedInEnvironment);
144
164
  AddAlias("--debug-port", "--inspect-port");
145
146
  AddOption("--inspect",
147
            "activate inspector on host:port (default: 127.0.0.1:9229)",
148
            &DebugOptions::inspector_enabled,
149
164
            kAllowedInEnvironment);
150
164
  AddAlias("--inspect=", { "--inspect-port", "--inspect" });
151
152
164
  AddOption("--debug", "", &DebugOptions::deprecated_debug);
153
164
  AddAlias("--debug=", { "--inspect-port", "--debug" });
154
155
  AddOption("--inspect-brk",
156
            "activate inspector on host:port and break at start of user script",
157
            &DebugOptions::break_first_line,
158
164
            kAllowedInEnvironment);
159
164
  Implies("--inspect-brk", "--inspect");
160
164
  AddAlias("--inspect-brk=", { "--inspect-port", "--inspect-brk" });
161
162
164
  AddOption("--inspect-brk-node", "", &DebugOptions::break_node_first_line);
163
164
  Implies("--inspect-brk-node", "--inspect");
164
164
  AddAlias("--inspect-brk-node=", { "--inspect-port", "--inspect-brk-node" });
165
166
164
  AddOption("--debug-brk", "", &DebugOptions::break_first_line);
167
164
  Implies("--debug-brk", "--debug");
168
164
  AddAlias("--debug-brk=", { "--inspect-port", "--debug-brk" });
169
164
}
170
171
164
EnvironmentOptionsParser::EnvironmentOptionsParser() {
172
  AddOption("--experimental-modules",
173
            "experimental ES Module support and caching modules",
174
            &EnvironmentOptions::experimental_modules,
175
164
            kAllowedInEnvironment);
176
  AddOption("--experimental-policy",
177
            "use the specified file as a "
178
            "security policy",
179
            &EnvironmentOptions::experimental_policy,
180
164
            kAllowedInEnvironment);
181
  AddOption("--experimental-repl-await",
182
            "experimental await keyword support in REPL",
183
            &EnvironmentOptions::experimental_repl_await,
184
164
            kAllowedInEnvironment);
185
  AddOption("--experimental-vm-modules",
186
            "experimental ES Module support in vm module",
187
            &EnvironmentOptions::experimental_vm_modules,
188
164
            kAllowedInEnvironment);
189
164
  AddOption("--experimental-worker", "", NoOp{}, kAllowedInEnvironment);
190
#ifdef NODE_REPORT
191
  AddOption("--experimental-report",
192
            "enable report generation",
193
            &EnvironmentOptions::experimental_report,
194
164
            kAllowedInEnvironment);
195
#endif  // NODE_REPORT
196
164
  AddOption("--expose-internals", "", &EnvironmentOptions::expose_internals);
197
  AddOption("--http-parser",
198
            "Select which HTTP parser to use; either 'legacy' or 'llhttp' "
199
            "(default: llhttp).",
200
            &EnvironmentOptions::http_parser,
201
164
            kAllowedInEnvironment);
202
  AddOption("--loader",
203
            "(with --experimental-modules) use the specified file as a "
204
            "custom loader",
205
            &EnvironmentOptions::userland_loader,
206
164
            kAllowedInEnvironment);
207
  AddOption("--no-deprecation",
208
            "silence deprecation warnings",
209
            &EnvironmentOptions::no_deprecation,
210
164
            kAllowedInEnvironment);
211
  AddOption("--no-force-async-hooks-checks",
212
            "disable checks for async_hooks",
213
            &EnvironmentOptions::no_force_async_hooks_checks,
214
164
            kAllowedInEnvironment);
215
  AddOption("--no-warnings",
216
            "silence all process warnings",
217
            &EnvironmentOptions::no_warnings,
218
164
            kAllowedInEnvironment);
219
  AddOption("--pending-deprecation",
220
            "emit pending deprecation warnings",
221
            &EnvironmentOptions::pending_deprecation,
222
164
            kAllowedInEnvironment);
223
  AddOption("--preserve-symlinks",
224
            "preserve symbolic links when resolving",
225
164
            &EnvironmentOptions::preserve_symlinks);
226
  AddOption("--preserve-symlinks-main",
227
            "preserve symbolic links when resolving the main module",
228
164
            &EnvironmentOptions::preserve_symlinks_main);
229
  AddOption("--prof-process",
230
            "process V8 profiler output generated using --prof",
231
164
            &EnvironmentOptions::prof_process);
232
  // Options after --prof-process are passed through to the prof processor.
233
164
  AddAlias("--prof-process", { "--prof-process", "--" });
234
  AddOption("--redirect-warnings",
235
            "write warnings to file instead of stderr",
236
            &EnvironmentOptions::redirect_warnings,
237
164
            kAllowedInEnvironment);
238
  AddOption("--throw-deprecation",
239
            "throw an exception on deprecations",
240
            &EnvironmentOptions::throw_deprecation,
241
164
            kAllowedInEnvironment);
242
  AddOption("--trace-deprecation",
243
            "show stack traces on deprecations",
244
            &EnvironmentOptions::trace_deprecation,
245
164
            kAllowedInEnvironment);
246
  AddOption("--trace-sync-io",
247
            "show stack trace when use of sync IO is detected after the "
248
            "first tick",
249
            &EnvironmentOptions::trace_sync_io,
250
164
            kAllowedInEnvironment);
251
  AddOption("--trace-warnings",
252
            "show stack traces on process warnings",
253
            &EnvironmentOptions::trace_warnings,
254
164
            kAllowedInEnvironment);
255
256
  AddOption("--check",
257
            "syntax check script without executing",
258
164
            &EnvironmentOptions::syntax_check_only);
259
164
  AddAlias("-c", "--check");
260
  // This option is only so that we can tell --eval with an empty string from
261
  // no eval at all. Having it not start with a dash makes it inaccessible
262
  // from the parser itself, but available for using Implies().
263
  // TODO(addaleax): When moving --help over to something generated from the
264
  // programmatic descriptions, this will need some special care.
265
  // (See also [ssl_openssl_cert_store] below.)
266
164
  AddOption("[has_eval_string]", "", &EnvironmentOptions::has_eval_string);
267
164
  AddOption("--eval", "evaluate script", &EnvironmentOptions::eval_string);
268
164
  Implies("--eval", "[has_eval_string]");
269
  AddOption("--print",
270
            "evaluate script and print result",
271
164
            &EnvironmentOptions::print_eval);
272
164
  AddAlias("-e", "--eval");
273
164
  AddAlias("--print <arg>", "-pe");
274
164
  AddAlias("-pe", { "--print", "--eval" });
275
164
  AddAlias("-p", "--print");
276
  AddOption("--require",
277
            "module to preload (option can be repeated)",
278
            &EnvironmentOptions::preload_modules,
279
164
            kAllowedInEnvironment);
280
164
  AddAlias("-r", "--require");
281
  AddOption("--interactive",
282
            "always enter the REPL even if stdin does not appear "
283
            "to be a terminal",
284
164
            &EnvironmentOptions::force_repl);
285
164
  AddAlias("-i", "--interactive");
286
287
164
  AddOption("--napi-modules", "", NoOp{}, kAllowedInEnvironment);
288
289
#if HAVE_OPENSSL
290
  AddOption("--tls-v1.0",
291
            "enable TLSv1.0 and greater by default",
292
            &EnvironmentOptions::tls_v1_0,
293
164
            kAllowedInEnvironment);
294
  AddOption("--tls-v1.1",
295
            "enable TLSv1.1 and greater by default",
296
            &EnvironmentOptions::tls_v1_1,
297
164
            kAllowedInEnvironment);
298
#endif
299
300
#if HAVE_INSPECTOR
301
  Insert(&DebugOptionsParser::instance,
302
164
         &EnvironmentOptions::get_debug_options);
303
#endif  // HAVE_INSPECTOR
304
164
}
305
306
164
PerIsolateOptionsParser::PerIsolateOptionsParser() {
307
  AddOption("--track-heap-objects",
308
            "track heap object allocations for heap snapshots",
309
            &PerIsolateOptions::track_heap_objects,
310
164
            kAllowedInEnvironment);
311
312
  // Explicitly add some V8 flags to mark them as allowed in NODE_OPTIONS.
313
  AddOption("--abort-on-uncaught-exception",
314
            "aborting instead of exiting causes a core file to be generated "
315
            "for analysis",
316
            V8Option{},
317
164
            kAllowedInEnvironment);
318
164
  AddOption("--max-old-space-size", "", V8Option{}, kAllowedInEnvironment);
319
164
  AddOption("--perf-basic-prof", "", V8Option{}, kAllowedInEnvironment);
320
164
  AddOption("--perf-prof", "", V8Option{}, kAllowedInEnvironment);
321
164
  AddOption("--stack-trace-limit", "", V8Option{}, kAllowedInEnvironment);
322
323
#ifdef NODE_REPORT
324
  AddOption("--diagnostic-report-uncaught-exception",
325
            "generate diagnostic report on uncaught exceptions",
326
            &PerIsolateOptions::report_uncaught_exception,
327
164
            kAllowedInEnvironment);
328
  AddOption("--diagnostic-report-on-signal",
329
            "generate diagnostic report upon receiving signals",
330
            &PerIsolateOptions::report_on_signal,
331
164
            kAllowedInEnvironment);
332
  AddOption("--diagnostic-report-on-fatalerror",
333
            "generate diagnostic report on fatal (internal) errors",
334
            &PerIsolateOptions::report_on_fatalerror,
335
164
            kAllowedInEnvironment);
336
  AddOption("--diagnostic-report-signal",
337
            "causes diagnostic report to be produced on provided signal,"
338
            " unsupported in Windows. (default: SIGUSR2)",
339
            &PerIsolateOptions::report_signal,
340
164
            kAllowedInEnvironment);
341
164
  Implies("--diagnostic-report-signal", "--diagnostic-report-on-signal");
342
  AddOption("--diagnostic-report-filename",
343
            "define custom report file name."
344
            " (default: YYYYMMDD.HHMMSS.PID.SEQUENCE#.txt)",
345
            &PerIsolateOptions::report_filename,
346
164
            kAllowedInEnvironment);
347
  AddOption("--diagnostic-report-directory",
348
            "define custom report pathname."
349
            " (default: current working directory of Node.js process)",
350
            &PerIsolateOptions::report_directory,
351
164
            kAllowedInEnvironment);
352
  AddOption("--diagnostic-report-verbose",
353
            "verbose option for report generation(true|false)."
354
            " (default: false)",
355
            &PerIsolateOptions::report_verbose,
356
164
            kAllowedInEnvironment);
357
#endif  // NODE_REPORT
358
359
  Insert(&EnvironmentOptionsParser::instance,
360
164
         &PerIsolateOptions::get_per_env_options);
361
164
}
362
363
164
PerProcessOptionsParser::PerProcessOptionsParser() {
364
  AddOption("--title",
365
            "the process title to use on startup",
366
            &PerProcessOptions::title,
367
164
            kAllowedInEnvironment);
368
  AddOption("--trace-event-categories",
369
            "comma separated list of trace event categories to record",
370
            &PerProcessOptions::trace_event_categories,
371
164
            kAllowedInEnvironment);
372
  AddOption("--trace-event-file-pattern",
373
            "Template string specifying the filepath for the trace-events "
374
            "data, it supports ${rotation} and ${pid}.",
375
            &PerProcessOptions::trace_event_file_pattern,
376
164
            kAllowedInEnvironment);
377
  AddAlias("--trace-events-enabled", {
378
164
    "--trace-event-categories", "v8,node,node.async_hooks" });
379
  AddOption("--max-http-header-size",
380
            "set the maximum size of HTTP headers (default: 8KB)",
381
            &PerProcessOptions::max_http_header_size,
382
164
            kAllowedInEnvironment);
383
  AddOption("--v8-pool-size",
384
            "set V8's thread pool size",
385
            &PerProcessOptions::v8_thread_pool_size,
386
164
            kAllowedInEnvironment);
387
  AddOption("--zero-fill-buffers",
388
            "automatically zero-fill all newly allocated Buffer and "
389
            "SlowBuffer instances",
390
            &PerProcessOptions::zero_fill_all_buffers,
391
164
            kAllowedInEnvironment);
392
393
164
  AddOption("--security-reverts", "", &PerProcessOptions::security_reverts);
394
  AddOption("--completion-bash",
395
            "print source-able bash completion script",
396
164
            &PerProcessOptions::print_bash_completion);
397
  AddOption("--help",
398
            "print node command line options",
399
164
            &PerProcessOptions::print_help);
400
164
  AddAlias("-h", "--help");
401
  AddOption(
402
164
      "--version", "print Node.js version", &PerProcessOptions::print_version);
403
164
  AddAlias("-v", "--version");
404
  AddOption("--v8-options",
405
            "print V8 command line options",
406
164
            &PerProcessOptions::print_v8_help);
407
408
#ifdef NODE_HAVE_I18N_SUPPORT
409
  AddOption("--icu-data-dir",
410
            "set ICU data load path to dir (overrides NODE_ICU_DATA)"
411
#ifndef NODE_HAVE_SMALL_ICU
412
            " (note: linked-in ICU data is present)\n"
413
#endif
414
            ,
415
            &PerProcessOptions::icu_data_dir,
416
164
            kAllowedInEnvironment);
417
#endif
418
419
#if HAVE_OPENSSL
420
  AddOption("--openssl-config",
421
            "load OpenSSL configuration from the specified file "
422
            "(overrides OPENSSL_CONF)",
423
            &PerProcessOptions::openssl_config,
424
164
            kAllowedInEnvironment);
425
  AddOption("--tls-cipher-list",
426
            "use an alternative default TLS cipher list",
427
            &PerProcessOptions::tls_cipher_list,
428
164
            kAllowedInEnvironment);
429
  AddOption("--use-openssl-ca",
430
            "use OpenSSL's default CA store"
431
#if defined(NODE_OPENSSL_CERT_STORE)
432
            " (default)"
433
#endif
434
            ,
435
            &PerProcessOptions::use_openssl_ca,
436
164
            kAllowedInEnvironment);
437
  AddOption("--use-bundled-ca",
438
            "use bundled CA store"
439
#if !defined(NODE_OPENSSL_CERT_STORE)
440
            " (default)"
441
#endif
442
            ,
443
            &PerProcessOptions::use_bundled_ca,
444
164
            kAllowedInEnvironment);
445
  // Similar to [has_eval_string] above, except that the separation between
446
  // this and use_openssl_ca only exists for option validation after parsing.
447
  // This is not ideal.
448
  AddOption("[ssl_openssl_cert_store]",
449
            "",
450
164
            &PerProcessOptions::ssl_openssl_cert_store);
451
164
  Implies("--use-openssl-ca", "[ssl_openssl_cert_store]");
452
164
  ImpliesNot("--use-bundled-ca", "[ssl_openssl_cert_store]");
453
#if NODE_FIPS_MODE
454
  AddOption("--enable-fips",
455
            "enable FIPS crypto at startup",
456
            &PerProcessOptions::enable_fips_crypto,
457
            kAllowedInEnvironment);
458
  AddOption("--force-fips",
459
            "force FIPS crypto (cannot be disabled)",
460
            &PerProcessOptions::force_fips_crypto,
461
            kAllowedInEnvironment);
462
#endif
463
#endif
464
465
  Insert(&PerIsolateOptionsParser::instance,
466
164
         &PerProcessOptions::get_per_isolate_options);
467
164
}
468
469
inline std::string RemoveBrackets(const std::string& host) {
470
  if (!host.empty() && host.front() == '[' && host.back() == ']')
471
    return host.substr(1, host.size() - 2);
472
  else
473
    return host;
474
}
475
476
inline int ParseAndValidatePort(const std::string& port,
477
                                std::vector<std::string>* errors) {
478
  char* endptr;
479
  errno = 0;
480
  const long result = strtol(port.c_str(), &endptr, 10);  // NOLINT(runtime/int)
481
  if (errno != 0 || *endptr != '\0'||
482
      (result != 0 && result < 1024) || result > 65535) {
483
    errors->push_back(" must be 0 or in range 1024 to 65535.");
484
  }
485
  return static_cast<int>(result);
486
}
487
488
HostPort SplitHostPort(const std::string& arg,
489
                      std::vector<std::string>* errors) {
490
  // remove_brackets only works if no port is specified
491
  // so if it has an effect only an IPv6 address was specified.
492
  std::string host = RemoveBrackets(arg);
493
  if (host.length() < arg.length())
494
    return HostPort{host, DebugOptions::kDefaultInspectorPort};
495
496
  size_t colon = arg.rfind(':');
497
  if (colon == std::string::npos) {
498
    // Either a port number or a host name.  Assume that
499
    // if it's not all decimal digits, it's a host name.
500
    for (char c : arg) {
501
      if (c < '0' || c > '9') {
502
        return HostPort{arg, DebugOptions::kDefaultInspectorPort};
503
      }
504
    }
505
    return HostPort { "", ParseAndValidatePort(arg, errors) };
506
  }
507
  // Host and port found:
508
  return HostPort { RemoveBrackets(arg.substr(0, colon)),
509
                    ParseAndValidatePort(arg.substr(colon + 1), errors) };
510
}
511
512
// Return a map containing all the options and their metadata as well
513
// as the aliases
514
164
void GetOptions(const FunctionCallbackInfo<Value>& args) {
515
164
  Mutex::ScopedLock lock(per_process::cli_options_mutex);
516
164
  Environment* env = Environment::GetCurrent(args);
517
164
  Isolate* isolate = env->isolate();
518
164
  Local<Context> context = env->context();
519
520
  // Temporarily act as if the current Environment's/IsolateData's options were
521
  // the default options, i.e. like they are the ones we'd access for global
522
  // options parsing, so that all options are available from the main parser.
523
328
  auto original_per_isolate = per_process::cli_options->per_isolate;
524
164
  per_process::cli_options->per_isolate = env->isolate_data()->options();
525
328
  auto original_per_env = per_process::cli_options->per_isolate->per_env;
526
164
  per_process::cli_options->per_isolate->per_env = env->options();
527
164
  OnScopeLeave on_scope_leave([&]() {
528
164
    per_process::cli_options->per_isolate->per_env = original_per_env;
529
164
    per_process::cli_options->per_isolate = original_per_isolate;
530
492
  });
531
532
164
  const auto& parser = PerProcessOptionsParser::instance;
533
534
164
  Local<Map> options = Map::New(isolate);
535
10988
  for (const auto& item : parser.options_) {
536
    Local<Value> value;
537
10824
    const auto& option_info = item.second;
538
10824
    auto field = option_info.field;
539
10824
    PerProcessOptions* opts = per_process::cli_options.get();
540


10824
    switch (option_info.type) {
541
      case kNoOp:
542
      case kV8Option:
543
1148
        value = Undefined(isolate);
544
1148
        break;
545
      case kBoolean:
546
13120
        value = Boolean::New(isolate, *parser.Lookup<bool>(field, opts));
547
6560
        break;
548
      case kInteger:
549
328
        value = Number::New(isolate, *parser.Lookup<int64_t>(field, opts));
550
164
        break;
551
      case kUInteger:
552
328
        value = Number::New(isolate, *parser.Lookup<uint64_t>(field, opts));
553
164
        break;
554
      case kString:
555
6888
        if (!ToV8Value(context, *parser.Lookup<std::string>(field, opts))
556
6888
                 .ToLocal(&value)) {
557
          return;
558
        }
559
2296
        break;
560
      case kStringList:
561
656
        if (!ToV8Value(context,
562
656
                       *parser.Lookup<std::vector<std::string>>(field, opts))
563
984
                 .ToLocal(&value)) {
564
          return;
565
        }
566
328
        break;
567
      case kHostPort: {
568
164
        const HostPort& host_port = *parser.Lookup<HostPort>(field, opts);
569
164
        Local<Object> obj = Object::New(isolate);
570
        Local<Value> host;
571

984
        if (!ToV8Value(context, host_port.host()).ToLocal(&host) ||
572


1476
            obj->Set(context, env->host_string(), host).IsNothing() ||
573
            obj->Set(context,
574
                     env->port_string(),
575

656
                     Integer::New(isolate, host_port.port()))
576
820
                .IsNothing()) {
577
          return;
578
        }
579
164
        value = obj;
580
164
        break;
581
      }
582
      default:
583
        UNREACHABLE();
584
    }
585
10824
    CHECK(!value.IsEmpty());
586
587
21648
    Local<Value> name = ToV8Value(context, item.first).ToLocalChecked();
588
10824
    Local<Object> info = Object::New(isolate);
589
    Local<Value> help_text;
590

75768
    if (!ToV8Value(context, option_info.help_text).ToLocal(&help_text) ||
591
32472
        !info->Set(context, env->help_text_string(), help_text)
592

97416
             .FromMaybe(false) ||
593
        !info->Set(context,
594
                   env->env_var_settings_string(),
595
                   Integer::New(isolate,
596

43296
                                static_cast<int>(option_info.env_setting)))
597

108240
             .FromMaybe(false) ||
598
        !info->Set(context,
599
                   env->type_string(),
600

43296
                   Integer::New(isolate, static_cast<int>(option_info.type)))
601

97416
             .FromMaybe(false) ||
602


108240
        info->Set(context, env->value_string(), value).IsNothing() ||
603

43296
        options->Set(context, name, info).IsEmpty()) {
604
      return;
605
    }
606
10824
  }
607
608
  Local<Value> aliases;
609
328
  if (!ToV8Value(context, parser.aliases_).ToLocal(&aliases)) return;
610
611
164
  Local<Object> ret = Object::New(isolate);
612



1312
  if (ret->Set(context, env->options_string(), options).IsNothing() ||
613

820
      ret->Set(context, env->aliases_string(), aliases).IsNothing()) {
614
    return;
615
  }
616
617
492
  args.GetReturnValue().Set(ret);
618
}
619
620
164
void Initialize(Local<Object> target,
621
                Local<Value> unused,
622
                Local<Context> context,
623
                void* priv) {
624
164
  Environment* env = Environment::GetCurrent(context);
625
164
  Isolate* isolate = env->isolate();
626
164
  env->SetMethodNoSideEffect(target, "getOptions", GetOptions);
627
628
164
  Local<Object> env_settings = Object::New(isolate);
629
656
  NODE_DEFINE_CONSTANT(env_settings, kAllowedInEnvironment);
630
656
  NODE_DEFINE_CONSTANT(env_settings, kDisallowedInEnvironment);
631
  target
632
      ->Set(
633
492
          context, FIXED_ONE_BYTE_STRING(isolate, "envSettings"), env_settings)
634
328
      .FromJust();
635
636
164
  Local<Object> types = Object::New(isolate);
637
656
  NODE_DEFINE_CONSTANT(types, kNoOp);
638
656
  NODE_DEFINE_CONSTANT(types, kV8Option);
639
656
  NODE_DEFINE_CONSTANT(types, kBoolean);
640
656
  NODE_DEFINE_CONSTANT(types, kInteger);
641
656
  NODE_DEFINE_CONSTANT(types, kUInteger);
642
656
  NODE_DEFINE_CONSTANT(types, kString);
643
656
  NODE_DEFINE_CONSTANT(types, kHostPort);
644
656
  NODE_DEFINE_CONSTANT(types, kStringList);
645
492
  target->Set(context, FIXED_ONE_BYTE_STRING(isolate, "types"), types)
646
328
      .FromJust();
647
164
}
648
649
}  // namespace options_parser
650
}  // namespace node
651
652

656
NODE_MODULE_CONTEXT_AWARE_INTERNAL(options, node::options_parser::Initialize)