| 1 | // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
| 2 | // for details. All rights reserved. Use of this source code is governed by a |
| 3 | // BSD-style license that can be found in the LICENSE file. |
| 4 | |
| 5 | #include "bin/options.h" |
| 6 | |
| 7 | namespace dart { |
| 8 | namespace bin { |
| 9 | |
| 10 | OptionProcessor* OptionProcessor::first_ = NULL; |
| 11 | |
| 12 | bool OptionProcessor::IsValidFlag(const char* name, |
| 13 | const char* prefix, |
| 14 | intptr_t prefix_length) { |
| 15 | const intptr_t name_length = strlen(name); |
| 16 | return ((name_length > prefix_length) && |
| 17 | (strncmp(name, prefix, prefix_length) == 0)); |
| 18 | } |
| 19 | |
| 20 | const char* OptionProcessor::ProcessOption(const char* option, |
| 21 | const char* name) { |
| 22 | const intptr_t length = strlen(name); |
| 23 | for (intptr_t i = 0; i < length; i++) { |
| 24 | if (option[i] != name[i]) { |
| 25 | if ((name[i] == '_') && (option[i] == '-')) { |
| 26 | continue; |
| 27 | } |
| 28 | return NULL; |
| 29 | } |
| 30 | } |
| 31 | return option + length; |
| 32 | } |
| 33 | |
| 34 | bool OptionProcessor::TryProcess(const char* option, |
| 35 | CommandLineOptions* vm_options) { |
| 36 | for (OptionProcessor* p = first_; p != NULL; p = p->next_) { |
| 37 | if (p->Process(option, vm_options)) { |
| 38 | return true; |
| 39 | } |
| 40 | } |
| 41 | return false; |
| 42 | } |
| 43 | |
| 44 | bool OptionProcessor::ProcessEnvironmentOption( |
| 45 | const char* arg, |
| 46 | CommandLineOptions* vm_options, |
| 47 | dart::SimpleHashMap** environment) { |
| 48 | ASSERT(arg != NULL); |
| 49 | ASSERT(environment != NULL); |
| 50 | if (*arg == '\0') { |
| 51 | return false; |
| 52 | } |
| 53 | if (*arg != '-') { |
| 54 | return false; |
| 55 | } |
| 56 | if (*(arg + 1) != 'D') { |
| 57 | return false; |
| 58 | } |
| 59 | arg = arg + 2; |
| 60 | if (*arg == '\0') { |
| 61 | return true; |
| 62 | } |
| 63 | if (*environment == NULL) { |
| 64 | *environment = new SimpleHashMap(&SimpleHashMap::SameStringValue, 4); |
| 65 | } |
| 66 | // Split the name=value part of the -Dname=value argument. |
| 67 | char* name; |
| 68 | char* value = NULL; |
| 69 | const char* equals_pos = strchr(arg, '='); |
| 70 | if (equals_pos == NULL) { |
| 71 | // No equal sign (name without value) currently not supported. |
| 72 | Syslog::PrintErr("No value given to -D option\n" ); |
| 73 | return true; |
| 74 | } |
| 75 | int name_len = equals_pos - arg; |
| 76 | if (name_len == 0) { |
| 77 | Syslog::PrintErr("No name given to -D option\n" ); |
| 78 | return true; |
| 79 | } |
| 80 | // Split name=value into name and value. |
| 81 | name = reinterpret_cast<char*>(malloc(name_len + 1)); |
| 82 | strncpy(name, arg, name_len); |
| 83 | name[name_len] = '\0'; |
| 84 | value = Utils::StrDup(equals_pos + 1); |
| 85 | SimpleHashMap::Entry* entry = |
| 86 | (*environment) |
| 87 | ->Lookup(GetHashmapKeyFromString(name), |
| 88 | SimpleHashMap::StringHash(name), true); |
| 89 | ASSERT(entry != NULL); // Lookup adds an entry if key not found. |
| 90 | if (entry->value != NULL) { |
| 91 | free(name); |
| 92 | free(entry->value); |
| 93 | } |
| 94 | entry->value = value; |
| 95 | return true; |
| 96 | } |
| 97 | |
| 98 | } // namespace bin |
| 99 | } // namespace dart |
| 100 | |