Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
src: make CLI options programatically accesible
Provide `internalBinding('options')` with some utilities
around making the options parser and current options values
programatically accessible.
  • Loading branch information
addaleax committed Aug 27, 2018
commit 3ef59611318b29606da7c4d2d52df4379eaa6318
4 changes: 4 additions & 0 deletions src/env.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ struct PackageConfig {
// for the sake of convenience. Strings should be ASCII-only.
#define PER_ISOLATE_STRING_PROPERTIES(V) \
V(address_string, "address") \
V(aliases_string, "aliases") \
V(args_string, "args") \
V(async, "async") \
V(async_ids_stack_string, "async_ids_stack") \
Expand Down Expand Up @@ -156,6 +157,7 @@ struct PackageConfig {
V(entries_string, "entries") \
V(entry_type_string, "entryType") \
V(env_pairs_string, "envPairs") \
V(env_var_settings_string, "envVarSettings") \
V(errno_string, "errno") \
V(error_string, "error") \
V(exit_code_string, "exitCode") \
Expand All @@ -176,6 +178,7 @@ struct PackageConfig {
V(get_shared_array_buffer_id_string, "_getSharedArrayBufferId") \
V(gid_string, "gid") \
V(handle_string, "handle") \
V(help_text_string, "helpText") \
V(homedir_string, "homedir") \
V(host_string, "host") \
V(hostmaster_string, "hostmaster") \
Expand Down Expand Up @@ -233,6 +236,7 @@ struct PackageConfig {
V(onunpipe_string, "onunpipe") \
V(onwrite_string, "onwrite") \
V(openssl_error_stack, "opensslErrorStack") \
V(options_string, "options") \
V(output_string, "output") \
V(order_string, "order") \
V(parse_error_string, "Parse Error") \
Expand Down
26 changes: 17 additions & 9 deletions src/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ typedef int mode_t;

namespace node {

using options_parser::kAllowedInEnvironment;
using options_parser::kDisallowedInEnvironment;
using v8::Array;
using v8::ArrayBuffer;
using v8::Boolean;
Expand Down Expand Up @@ -183,6 +185,7 @@ bool linux_at_secure = false;
// process-relative uptime base, initialized at start-up
double prog_start_time;

Mutex per_process_opts_mutex;
std::shared_ptr<PerProcessOptions> per_process_opts {
new PerProcessOptions() };

Expand Down Expand Up @@ -2346,8 +2349,6 @@ void LoadEnvironment(Environment* env) {
}

static void PrintHelp() {
// XXX: If you add an option here, please also add it to doc/node.1 and
// doc/api/cli.md
printf("Usage: node [options] [ -e script | script.js | - ] [arguments]\n"
" node inspect script.js [arguments]\n"
"\n"
Expand Down Expand Up @@ -2747,13 +2748,20 @@ void ProcessArgv(std::vector<std::string>* args,
// Parse a few arguments which are specific to Node.
std::vector<std::string> v8_args;
std::string error;
PerProcessOptionsParser::instance.Parse(
args,
exec_args,
&v8_args,
per_process_opts.get(),
is_env ? kAllowedInEnvironment : kDisallowedInEnvironment,
&error);

{
// TODO(addaleax): The mutex here should ideally be held during the
// entire function, but that doesn't play well with the exit() calls below.
Mutex::ScopedLock lock(per_process_opts_mutex);
options_parser::PerProcessOptionsParser::instance.Parse(
args,
exec_args,
&v8_args,
per_process_opts.get(),
is_env ? kAllowedInEnvironment : kDisallowedInEnvironment,
&error);
}

if (!error.empty()) {
fprintf(stderr, "%s: %s\n", args->at(0).c_str(), error.c_str());
exit(9);
Expand Down
2 changes: 2 additions & 0 deletions src/node_internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ struct sockaddr;
V(js_stream) \
V(messaging) \
V(module_wrap) \
V(options) \
V(os) \
V(performance) \
V(pipe_wrap) \
Expand Down Expand Up @@ -176,6 +177,7 @@ extern Mutex environ_mutex;
// Tells whether it is safe to call v8::Isolate::GetCurrent().
extern bool v8_initialized;

extern Mutex per_process_opts_mutex;
extern std::shared_ptr<PerProcessOptions> per_process_opts;

extern const char* const environment_flags[];
Expand Down
90 changes: 51 additions & 39 deletions src/node_options-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,73 +21,88 @@ EnvironmentOptions* PerIsolateOptions::get_per_env_options() {
return per_env.get();
}

namespace options_parser {

template <typename Options>
void OptionsParser<Options>::AddOption(const std::string& name,
const std::string& help_text,
bool Options::* field,
OptionEnvvarSettings env_setting) {
options_.emplace(name, OptionInfo {
kBoolean,
std::make_shared<SimpleOptionField<bool>>(field),
env_setting
});
options_.emplace(name,
OptionInfo{kBoolean,
std::make_shared<SimpleOptionField<bool>>(field),
env_setting,
help_text});
}

template <typename Options>
void OptionsParser<Options>::AddOption(const std::string& name,
const std::string& help_text,
int64_t Options::* field,
OptionEnvvarSettings env_setting) {
options_.emplace(name, OptionInfo {
kInteger,
std::make_shared<SimpleOptionField<int64_t>>(field),
env_setting
});
options_.emplace(
name,
OptionInfo{kInteger,
std::make_shared<SimpleOptionField<int64_t>>(field),
env_setting,
help_text});
}

template <typename Options>
void OptionsParser<Options>::AddOption(const std::string& name,
const std::string& help_text,
std::string Options::* field,
OptionEnvvarSettings env_setting) {
options_.emplace(name, OptionInfo {
kString,
std::make_shared<SimpleOptionField<std::string>>(field),
env_setting
});
options_.emplace(
name,
OptionInfo{kString,
std::make_shared<SimpleOptionField<std::string>>(field),
env_setting,
help_text});
}

template <typename Options>
void OptionsParser<Options>::AddOption(
const std::string& name,
const std::string& help_text,
std::vector<std::string> Options::* field,
OptionEnvvarSettings env_setting) {
options_.emplace(name, OptionInfo {
kStringList,
std::make_shared<SimpleOptionField<std::vector<std::string>>>(field),
env_setting
env_setting,
help_text
});
}

template <typename Options>
void OptionsParser<Options>::AddOption(const std::string& name,
const std::string& help_text,
HostPort Options::* field,
OptionEnvvarSettings env_setting) {
options_.emplace(name, OptionInfo {
kHostPort,
std::make_shared<SimpleOptionField<HostPort>>(field),
env_setting
});
options_.emplace(
name,
OptionInfo{kHostPort,
std::make_shared<SimpleOptionField<HostPort>>(field),
env_setting,
help_text});
}

template <typename Options>
void OptionsParser<Options>::AddOption(const std::string& name, NoOp no_op_tag,
void OptionsParser<Options>::AddOption(const std::string& name,
const std::string& help_text,
NoOp no_op_tag,
OptionEnvvarSettings env_setting) {
options_.emplace(name, OptionInfo { kNoOp, nullptr, env_setting });
options_.emplace(name, OptionInfo{kNoOp, nullptr, env_setting, help_text});
}

template <typename Options>
void OptionsParser<Options>::AddOption(const std::string& name,
const std::string& help_text,
V8Option v8_option_tag,
OptionEnvvarSettings env_setting) {
options_.emplace(name, OptionInfo { kV8Option, nullptr, env_setting });
options_.emplace(name,
OptionInfo{kV8Option, nullptr, env_setting, help_text});
}

template <typename Options>
Expand Down Expand Up @@ -161,11 +176,10 @@ template <typename ChildOptions>
auto OptionsParser<Options>::Convert(
typename OptionsParser<ChildOptions>::OptionInfo original,
ChildOptions* (Options::* get_child)()) {
return OptionInfo {
original.type,
Convert(original.field, get_child),
original.env_setting
};
return OptionInfo{original.type,
Convert(original.field, get_child),
original.env_setting,
original.help_text};
}

template <typename Options>
Expand Down Expand Up @@ -385,24 +399,21 @@ void OptionsParser<Options>::Parse(

switch (info.type) {
case kBoolean:
*std::static_pointer_cast<OptionField<bool>>(info.field)
->Lookup(options) = true;
*Lookup<bool>(info.field, options) = true;
break;
case kInteger:
*std::static_pointer_cast<OptionField<int64_t>>(info.field)
->Lookup(options) = std::atoll(value.c_str());
*Lookup<int64_t>(info.field, options) = std::atoll(value.c_str());
break;
case kString:
*std::static_pointer_cast<OptionField<std::string>>(info.field)
->Lookup(options) = value;
*Lookup<std::string>(info.field, options) = value;
break;
case kStringList:
std::static_pointer_cast<OptionField<std::vector<std::string>>>(
info.field)->Lookup(options)->emplace_back(std::move(value));
Lookup<std::vector<std::string>>(info.field, options)
->emplace_back(std::move(value));
break;
case kHostPort:
std::static_pointer_cast<OptionField<HostPort>>(info.field)
->Lookup(options)->Update(SplitHostPort(value, error));
Lookup<HostPort>(info.field, options)
->Update(SplitHostPort(value, error));
break;
case kNoOp:
break;
Expand All @@ -415,6 +426,7 @@ void OptionsParser<Options>::Parse(
}
}

} // namespace options_parser
} // namespace node

#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
Expand Down
Loading