Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/marian-nmt/sentencepiece.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTaku Kudo <taku@google.com>2017-03-07 13:43:50 +0300
committerTaku Kudo <taku@google.com>2017-03-07 13:43:50 +0300
commit2928ce5307224ea4c012fc6cbd7a098c486590b6 (patch)
tree38b679886855a7a6b80fdc61f2f62c952cf3bfb7 /src/flags.cc
Initialize repository
Diffstat (limited to 'src/flags.cc')
-rw-r--r--src/flags.cc238
1 files changed, 238 insertions, 0 deletions
diff --git a/src/flags.cc b/src/flags.cc
new file mode 100644
index 0000000..bdc4571
--- /dev/null
+++ b/src/flags.cc
@@ -0,0 +1,238 @@
+// Copyright 2016 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.!
+
+#include "flags.h"
+#include "common.h"
+
+#include <algorithm>
+#include <cctype>
+#include <iostream>
+#include <map>
+#include <sstream>
+#include <string>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+namespace sentencepiece {
+namespace flags {
+
+struct Flag {
+ int type;
+ void *storage;
+ const void *default_storage;
+ std::string help;
+};
+
+namespace {
+using FlagMap = std::map<std::string, Flag *>;
+
+FlagMap *GetFlagMap() {
+ static FlagMap flag_map;
+ return &flag_map;
+}
+
+bool IsTrue(const std::string &value) {
+ const char *kTrue[] = {"1", "t", "true", "y", "yes"};
+ const char *kFalse[] = {"0", "f", "false", "n", "no"};
+ std::string lower_value = value;
+ std::transform(lower_value.begin(), lower_value.end(), lower_value.begin(),
+ ::tolower);
+ for (size_t i = 0; i < 5; ++i) {
+ if (lower_value == kTrue[i]) {
+ return true;
+ } else if (lower_value == kFalse[i]) {
+ return false;
+ }
+ }
+ LOG(FATAL) << "cannot parse boolean value: " << value;
+ return false;
+}
+
+bool SetFlag(const std::string &name, const std::string &value) {
+ auto it = GetFlagMap()->find(name);
+ if (it == GetFlagMap()->end()) {
+ return false;
+ }
+
+ std::string v = value;
+ Flag *flag = it->second;
+
+ // If empty value is set, we assume true or emtpy string is set
+ // for boolean or string option. With other types, setting fails.
+ if (value.empty()) {
+ switch (flag->type) {
+ case B:
+ v = "true";
+ break;
+ case S:
+ v = "";
+ break;
+ default:
+ return false;
+ }
+ }
+
+ switch (flag->type) {
+ case I:
+ *reinterpret_cast<int32 *>(flag->storage) = atoi(v.c_str());
+ break;
+ case B:
+ *(reinterpret_cast<bool *>(flag->storage)) = IsTrue(v);
+ break;
+ case I64:
+ *reinterpret_cast<int64 *>(flag->storage) = atoll(v.c_str());
+ break;
+ case U64:
+ *reinterpret_cast<uint64 *>(flag->storage) = atoll(v.c_str());
+ break;
+ case D:
+ *reinterpret_cast<double *>(flag->storage) = strtod(v.c_str(), nullptr);
+ break;
+ case S:
+ *reinterpret_cast<std::string *>(flag->storage) = v;
+ break;
+ default:
+ break;
+ }
+
+ return true;
+}
+
+bool CommandLineGetFlag(int argc, char **argv, std::string *key,
+ std::string *value, int *used_args) {
+ key->clear();
+ value->clear();
+
+ *used_args = 1;
+ const char *start = argv[0];
+ if (start[0] != '-') {
+ return false;
+ }
+
+ ++start;
+ if (start[0] == '-') ++start;
+ const std::string arg = start;
+ const size_t n = arg.find("=");
+ if (n != std::string::npos) {
+ *key = arg.substr(0, n);
+ *value = arg.substr(n + 1, arg.size() - n);
+ return true;
+ }
+
+ key->assign(arg);
+ value->clear();
+
+ if (argc == 1) {
+ return true;
+ }
+ start = argv[1];
+ if (start[0] == '-') {
+ return true;
+ }
+
+ *used_args = 2;
+ value->assign(start);
+ return true;
+}
+} // namespace
+
+FlagRegister::FlagRegister(const char *name, void *storage,
+ const void *default_storage, int shortype,
+ const char *help)
+ : flag_(new Flag) {
+ flag_->type = shortype;
+ flag_->storage = storage;
+ flag_->default_storage = default_storage;
+ flag_->help = help;
+ GetFlagMap()->insert(std::make_pair(std::string(name), flag_.get()));
+}
+
+FlagRegister::~FlagRegister() {}
+
+std::string PrintHelp(const char *programname) {
+ std::ostringstream os;
+ os << PACKAGE_STRING << "\n\n";
+ os << "Usage: " << programname << " [options] files\n\n";
+
+ for (const auto &it : *GetFlagMap()) {
+ os << " --" << it.first << " (" << it.second->help << ")";
+ const Flag *flag = it.second;
+ switch (flag->type) {
+ case I:
+ os << " type: int32 default: "
+ << *(reinterpret_cast<const int *>(flag->default_storage)) << '\n';
+ break;
+ case B:
+ os << " type: bool default: "
+ << (*(reinterpret_cast<const bool *>(flag->default_storage))
+ ? "true"
+ : "false")
+ << '\n';
+ break;
+ case I64:
+ os << " type: int64 default: "
+ << *(reinterpret_cast<const int64 *>(flag->default_storage)) << '\n';
+ break;
+ case U64:
+ os << " type: uint64 default: "
+ << *(reinterpret_cast<const uint64 *>(flag->default_storage))
+ << '\n';
+ break;
+ case D:
+ os << " type: double default: "
+ << *(reinterpret_cast<const double *>(flag->default_storage))
+ << '\n';
+ break;
+ case S:
+ os << " type: string default: "
+ << *(reinterpret_cast<const std::string *>(flag->default_storage))
+ << '\n';
+ break;
+ default:
+ break;
+ }
+ }
+
+ os << "\n\n";
+
+ return os.str();
+}
+
+void ParseCommandLineFlags(int argc, char **argv,
+ std::vector<std::string> *rest_flags) {
+ int used_argc = 0;
+ std::string key, value;
+
+ for (int i = 1; i < argc; i += used_argc) {
+ if (!CommandLineGetFlag(argc - i, argv + i, &key, &value, &used_argc)) {
+ if (rest_flags) rest_flags->push_back(std::string(argv[i]));
+ continue;
+ }
+ if (key == "help") {
+ std::cout << PrintHelp(argv[0]);
+ error::Exit(0);
+ } else if (key == "version") {
+ std::cout << PACKAGE_STRING << " " << VERSION << std::endl;
+ error::Exit(0);
+ } else if (!SetFlag(key, value)) {
+ std::cerr << "Unknown/Invalid flag " << key << "\n\n"
+ << PrintHelp(argv[0]);
+ error::Exit(1);
+ }
+ }
+}
+} // namespace flags
+} // namespace sentencepiece