dart-sdk/runtime/bin/options.cc
Ben Konyi 848121e6d4 Reland "[ CLI ] Improved consistency of -D and --define across tools and commands"
- Added support for --define to the VM and dart2js
- Added support for -D and --define for `dart run` and `dart compile js`

Remaining improvements:
- Add support for providing multiple comma separated values for `dart
  run`, `dart`, and `dart2js`

Related issue: https://github.com/dart-lang/sdk/issues/44562

TEST=Updated CLI tests and added new dart2js tests.

This reverts commit e49937769f.

Change-Id: I5f9275b829665eb5e8695403d67f230e752ab0e6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/183180
Commit-Queue: Ben Konyi <bkonyi@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
2021-02-05 23:53:28 +00:00

120 lines
3.5 KiB
C++

// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#include "bin/options.h"
namespace dart {
namespace bin {
OptionProcessor* OptionProcessor::first_ = NULL;
bool OptionProcessor::IsValidFlag(const char* name) {
return name[0] == '-' && name[1] == '-' && name[2] != '\0';
}
bool OptionProcessor::IsValidShortFlag(const char* name) {
return name[0] == '-' && name[1] != '\0';
}
const char* OptionProcessor::ProcessOption(const char* option,
const char* name) {
const intptr_t length = strlen(name);
for (intptr_t i = 0; i < length; i++) {
if (option[i] != name[i]) {
if ((name[i] == '_') && (option[i] == '-')) {
continue;
}
return NULL;
}
}
return option + length;
}
bool OptionProcessor::TryProcess(const char* option,
CommandLineOptions* vm_options) {
for (OptionProcessor* p = first_; p != NULL; p = p->next_) {
if (p->Process(option, vm_options)) {
return true;
}
}
return false;
}
static bool IsPrefix(const char* prefix, size_t prefix_len, const char* str) {
ASSERT(prefix != nullptr);
ASSERT(str != nullptr);
const size_t str_len = strlen(str);
if (str_len < prefix_len) {
return false;
}
return strncmp(prefix, str, prefix_len) == 0;
}
bool OptionProcessor::ProcessEnvironmentOption(
const char* arg,
CommandLineOptions* vm_options,
dart::SimpleHashMap** environment) {
ASSERT(arg != NULL);
ASSERT(environment != NULL);
const char* kShortPrefix = "-D";
const char* kLongPrefix = "--define=";
const int kShortPrefixLen = strlen(kShortPrefix);
const int kLongPrefixLen = strlen(kLongPrefix);
const bool is_short_form = IsPrefix(kShortPrefix, kShortPrefixLen, arg);
const bool is_long_form = IsPrefix(kLongPrefix, kLongPrefixLen, arg);
if (is_short_form) {
arg = arg + kShortPrefixLen;
} else if (is_long_form) {
arg = arg + kLongPrefixLen;
} else {
return false;
}
if (*arg == '\0') {
return true;
}
if (*environment == NULL) {
*environment = new SimpleHashMap(&SimpleHashMap::SameStringValue, 4);
}
// Split the name=value part of the -Dname=value argument.
char* name;
char* value = NULL;
const char* equals_pos = strchr(arg, '=');
if (equals_pos == NULL) {
// No equal sign (name without value) currently not supported.
if (is_short_form) {
Syslog::PrintErr("No value given to -D option\n");
} else {
Syslog::PrintErr("No value given to --define option\n");
}
return true;
}
int name_len = equals_pos - arg;
if (name_len == 0) {
if (is_short_form) {
Syslog::PrintErr("No name given to -D option\n");
} else {
Syslog::PrintErr("No name given to --define option\n");
}
return true;
}
// Split name=value into name and value.
name = reinterpret_cast<char*>(malloc(name_len + 1));
strncpy(name, arg, name_len);
name[name_len] = '\0';
value = Utils::StrDup(equals_pos + 1);
SimpleHashMap::Entry* entry =
(*environment)
->Lookup(GetHashmapKeyFromString(name),
SimpleHashMap::StringHash(name), true);
ASSERT(entry != NULL); // Lookup adds an entry if key not found.
if (entry->value != NULL) {
free(name);
free(entry->value);
}
entry->value = value;
return true;
}
} // namespace bin
} // namespace dart