Skip to content

Commit ea66bfc

Browse files
committed
src: add NODE_OPTIONS_STANDALONE
1 parent d08a1f9 commit ea66bfc

3 files changed

Lines changed: 181 additions & 59 deletions

File tree

argparse.cc

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
#include "src/node_options.h"
2+
#include "src/util.h"
3+
4+
#include <iostream>
5+
#include <ranges>
6+
#include <string>
7+
#include <vector>
8+
9+
extern "C" {
10+
11+
uint64_t uv_get_total_memory() {
12+
return 0;
13+
}
14+
15+
uint64_t uv_get_constrained_memory() {
16+
return 0;
17+
}
18+
};
19+
20+
namespace node {
21+
22+
void Assert(const AssertionInfo& info) {
23+
fprintf(stderr,
24+
"\n"
25+
" # %s at %s\n"
26+
" # Assertion failed: %s\n\n",
27+
info.function ? info.function : "(unknown function)",
28+
info.file_line ? info.file_line : "(unknown source location)",
29+
info.message);
30+
31+
fflush(stderr);
32+
33+
abort();
34+
}
35+
36+
} // namespace node
37+
38+
int main(int argc, char** argv) {
39+
std::vector<std::string> args(argv, argv + argc);
40+
std::vector<std::string> exec_args;
41+
std::vector<std::string> errors;
42+
43+
node::PerProcessOptions cli_options;
44+
45+
cli_options.cmdline = args;
46+
47+
if (const char* result = std::getenv("NODE_OPTIONS")) {
48+
std::string node_options(result);
49+
50+
std::vector<std::string> env_argv =
51+
node::ParseNodeOptionsEnvVar(node_options, &errors);
52+
for (auto error : errors) {
53+
std::cout << "error: " << error << std::endl;
54+
}
55+
if (!errors.empty()) return 1;
56+
57+
env_argv.insert(env_argv.begin(), args.at(0));
58+
59+
{
60+
std::vector<std::string> v8_args;
61+
node::options_parser::Parse(&env_argv,
62+
nullptr,
63+
&v8_args,
64+
&cli_options,
65+
node::OptionEnvvarSettings::kAllowedInEnvvar,
66+
&errors);
67+
68+
for (auto arg : v8_args | std::views::drop(1)) {
69+
std::cout << "v8_arg: " << arg << std::endl;
70+
}
71+
}
72+
}
73+
74+
node::HandleEnvOptions(cli_options.per_isolate->per_env,
75+
[](const char* name) {
76+
const char* value = std::getenv(name);
77+
if (value != nullptr) {
78+
return std::string(value);
79+
}
80+
return std::string("");
81+
});
82+
83+
{
84+
std::vector<std::string> v8_args;
85+
node::options_parser::Parse(&args,
86+
&exec_args,
87+
&v8_args,
88+
&cli_options,
89+
node::OptionEnvvarSettings::kDisallowedInEnvvar,
90+
&errors);
91+
92+
for (auto arg : v8_args | std::views::drop(1)) {
93+
std::cout << "v8_arg: " << arg << std::endl;
94+
}
95+
}
96+
97+
for (auto arg : args) {
98+
std::cout << "arg: " << arg << std::endl;
99+
}
100+
101+
for (auto arg : exec_args) {
102+
std::cout << "exec_arg: " << arg << std::endl;
103+
}
104+
105+
for (auto error : errors) {
106+
std::cout << "error: " << error << std::endl;
107+
}
108+
}

src/node_options.cc

Lines changed: 69 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <string_view>
2222
#include <vector>
2323

24+
#ifndef NODE_OPTIONS_STANDALONE
2425
using v8::Boolean;
2526
using v8::Context;
2627
using v8::FunctionCallbackInfo;
@@ -36,12 +37,16 @@ using v8::Object;
3637
using v8::String;
3738
using v8::Undefined;
3839
using v8::Value;
40+
#endif // NODE_OPTIONS_STANDALONE
41+
3942
namespace node {
4043

44+
#ifndef NODE_OPTIONS_STANDALONE
4145
namespace per_process {
4246
Mutex cli_options_mutex;
4347
std::shared_ptr<PerProcessOptions> cli_options{new PerProcessOptions()};
4448
} // namespace per_process
49+
#endif // NODE_OPTIONS_STANDALONE
4550

4651
void DebugOptions::CheckOptions(std::vector<std::string>* errors,
4752
std::vector<std::string>* argv) {
@@ -293,64 +298,6 @@ void EnvironmentOptions::CheckOptions(std::vector<std::string>* errors,
293298

294299
namespace options_parser {
295300

296-
// Helper function to convert option types to their string representation
297-
// and add them to a V8 Map
298-
static bool AddOptionTypeToMap(Isolate* isolate,
299-
Local<Context> context,
300-
Local<Map> map,
301-
const std::string& option_name,
302-
const OptionType& option_type) {
303-
std::string type;
304-
switch (static_cast<int>(option_type)) {
305-
case 0: // No-op
306-
case 1: // V8 flags
307-
break; // V8 and NoOp flags are not supported
308-
309-
case 2:
310-
type = "boolean";
311-
break;
312-
case 3: // integer
313-
case 4: // unsigned integer
314-
case 6: // host port
315-
type = "number";
316-
break;
317-
case 5: // string
318-
type = "string";
319-
break;
320-
case 7: // string array
321-
type = "array";
322-
break;
323-
default:
324-
UNREACHABLE();
325-
}
326-
327-
if (type.empty()) {
328-
return true; // Skip this entry but continue processing
329-
}
330-
331-
Local<String> option_key;
332-
if (!String::NewFromUtf8(isolate,
333-
option_name.data(),
334-
v8::NewStringType::kNormal,
335-
option_name.size())
336-
.ToLocal(&option_key)) {
337-
return true; // Skip this entry but continue processing
338-
}
339-
340-
Local<String> type_value;
341-
if (!String::NewFromUtf8(
342-
isolate, type.data(), v8::NewStringType::kNormal, type.size())
343-
.ToLocal(&type_value)) {
344-
return true; // Skip this entry but continue processing
345-
}
346-
347-
if (map->Set(context, option_key, type_value).IsEmpty()) {
348-
return false; // Error occurred, stop processing
349-
}
350-
351-
return true;
352-
}
353-
354301
class DebugOptionsParser : public OptionsParser<DebugOptions> {
355302
public:
356303
DebugOptionsParser();
@@ -1445,6 +1392,65 @@ HostPort SplitHostPort(const std::string& arg,
14451392
ParseAndValidatePort(arg.substr(colon + 1), errors) };
14461393
}
14471394

1395+
#ifndef NODE_OPTIONS_STANDALONE
1396+
// Helper function to convert option types to their string representation
1397+
// and add them to a V8 Map
1398+
static bool AddOptionTypeToMap(Isolate* isolate,
1399+
Local<Context> context,
1400+
Local<Map> map,
1401+
const std::string& option_name,
1402+
const OptionType& option_type) {
1403+
std::string type;
1404+
switch (static_cast<int>(option_type)) {
1405+
case 0: // No-op
1406+
case 1: // V8 flags
1407+
break; // V8 and NoOp flags are not supported
1408+
1409+
case 2:
1410+
type = "boolean";
1411+
break;
1412+
case 3: // integer
1413+
case 4: // unsigned integer
1414+
case 6: // host port
1415+
type = "number";
1416+
break;
1417+
case 5: // string
1418+
type = "string";
1419+
break;
1420+
case 7: // string array
1421+
type = "array";
1422+
break;
1423+
default:
1424+
UNREACHABLE();
1425+
}
1426+
1427+
if (type.empty()) {
1428+
return true; // Skip this entry but continue processing
1429+
}
1430+
1431+
Local<String> option_key;
1432+
if (!String::NewFromUtf8(isolate,
1433+
option_name.data(),
1434+
v8::NewStringType::kNormal,
1435+
option_name.size())
1436+
.ToLocal(&option_key)) {
1437+
return true; // Skip this entry but continue processing
1438+
}
1439+
1440+
Local<String> type_value;
1441+
if (!String::NewFromUtf8(
1442+
isolate, type.data(), v8::NewStringType::kNormal, type.size())
1443+
.ToLocal(&type_value)) {
1444+
return true; // Skip this entry but continue processing
1445+
}
1446+
1447+
if (map->Set(context, option_key, type_value).IsEmpty()) {
1448+
return false; // Error occurred, stop processing
1449+
}
1450+
1451+
return true;
1452+
}
1453+
14481454
std::string GetBashCompletion() {
14491455
Mutex::ScopedLock lock(per_process::cli_options_mutex);
14501456
const auto& parser = _ppop_instance;
@@ -2033,14 +2039,17 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
20332039
registry->Register(GetEnvOptionsInputType);
20342040
registry->Register(GetNamespaceOptionsInputType);
20352041
}
2042+
#endif // NODE_OPTIONS_STANDALONE
20362043
} // namespace options_parser
20372044

2045+
#ifndef NODE_OPTIONS_STANDALONE
20382046
void HandleEnvOptions(std::shared_ptr<EnvironmentOptions> env_options) {
20392047
HandleEnvOptions(env_options, [](const char* name) {
20402048
std::string text;
20412049
return credentials::SafeGetenv(name, &text) ? text : "";
20422050
});
20432051
}
2052+
#endif // NODE_OPTIONS_STANDALONE
20442053

20452054
void HandleEnvOptions(std::shared_ptr<EnvironmentOptions> env_options,
20462055
std::function<std::string(const char*)> opt_getter) {
@@ -2100,6 +2109,8 @@ std::vector<std::string> ParseNodeOptionsEnvVar(
21002109
}
21012110
} // namespace node
21022111

2112+
#ifndef NODE_OPTIONS_STANDALONE
21032113
NODE_BINDING_CONTEXT_AWARE_INTERNAL(options, node::options_parser::Initialize)
21042114
NODE_BINDING_EXTERNAL_REFERENCE(
21052115
options, node::options_parser::RegisterExternalReferences)
2116+
#endif // NODE_OPTIONS_STANDALONE

src/node_options.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,6 @@ namespace options_parser {
389389

390390
HostPort SplitHostPort(const std::string& arg,
391391
std::vector<std::string>* errors);
392-
void GetOptions(const v8::FunctionCallbackInfo<v8::Value>& args);
393392
std::string GetBashCompletion();
394393

395394
enum OptionType {
@@ -638,6 +637,7 @@ class OptionsParser {
638637
template <typename OtherOptions>
639638
friend class OptionsParser;
640639

640+
#ifndef NODE_OPTIONS_STANDALONE
641641
friend void GetCLIOptionsValues(
642642
const v8::FunctionCallbackInfo<v8::Value>& args);
643643
friend void GetCLIOptionsInfo(
@@ -652,6 +652,7 @@ class OptionsParser {
652652
const v8::FunctionCallbackInfo<v8::Value>& args);
653653
friend void GetOptionsAsFlags(
654654
const v8::FunctionCallbackInfo<v8::Value>& args);
655+
#endif // NODE_OPTIONS_STANDALONE
655656
};
656657

657658
using StringVector = std::vector<std::string>;
@@ -663,6 +664,7 @@ void Parse(
663664

664665
} // namespace options_parser
665666

667+
#ifndef NODE_OPTIONS_STANDALONE
666668
namespace per_process {
667669

668670
extern Mutex cli_options_mutex;
@@ -671,6 +673,7 @@ extern NODE_EXTERN_PRIVATE std::shared_ptr<PerProcessOptions> cli_options;
671673
} // namespace per_process
672674

673675
void HandleEnvOptions(std::shared_ptr<EnvironmentOptions> env_options);
676+
#endif // NODE_OPTIONS_STANDALONE
674677
void HandleEnvOptions(std::shared_ptr<EnvironmentOptions> env_options,
675678
std::function<std::string(const char*)> opt_getter);
676679

0 commit comments

Comments
 (0)