Merge "Define arguments for commands in dicttoolkit."

main
Keisuke Kuroyanagi 2014-11-16 17:23:55 +00:00 committed by Android (Google) Code Review
commit e7a72de8c2
16 changed files with 455 additions and 9 deletions

View File

@ -25,10 +25,16 @@ LATIN_IME_DICT_TOOLKIT_SRC_FILES := \
$(addprefix offdevice_intermediate_dict/, \ $(addprefix offdevice_intermediate_dict/, \
offdevice_intermediate_dict.cpp) \ offdevice_intermediate_dict.cpp) \
$(addprefix utils/, \ $(addprefix utils/, \
arguments_parser.cpp \
command_utils.cpp \ command_utils.cpp \
utf8_utils.cpp) utf8_utils.cpp)
LATIN_IME_DICT_TOOLKIT_TEST_FILES := \ LATIN_IME_DICT_TOOLKIT_TEST_FILES := \
$(addprefix command_executors/, \
diff_executor_test.cpp \
header_executor_test.cpp \
info_executor_test.cpp \
makedict_executor_test.cpp) \
dict_toolkit_defines_test.cpp \ dict_toolkit_defines_test.cpp \
$(addprefix offdevice_intermediate_dict/, \ $(addprefix offdevice_intermediate_dict/, \
offdevice_intermediate_dict_test.cpp) \ offdevice_intermediate_dict_test.cpp) \

View File

@ -30,8 +30,19 @@ const char *const DiffExecutor::COMMAND_NAME = "diff";
/* static */ void DiffExecutor::printUsage() { /* static */ void DiffExecutor::printUsage() {
printf("*** %s\n", COMMAND_NAME); printf("*** %s\n", COMMAND_NAME);
printf("Usage: %s\n", COMMAND_NAME); getArgumentsParser().printUsage(COMMAND_NAME, "Shows differences between two dictionaries.");
printf("Shows differences between two dictionaries.\n\n"); }
/* static */ const ArgumentsParser DiffExecutor::getArgumentsParser() {
std::unordered_map<std::string, OptionSpec> optionSpecs;
optionSpecs["p"] = OptionSpec::switchOption("(plumbing) produce output suitable for a script");
const std::vector<ArgumentSpec> argumentSpecs = {
ArgumentSpec::singleArgument("dict1", "dictionary file"),
ArgumentSpec::singleArgument("dict2", "dictionary file")
};
return ArgumentsParser(std::move(optionSpecs), std::move(argumentSpecs));
} }
} // namespace dicttoolkit } // namespace dicttoolkit

View File

@ -18,6 +18,7 @@
#define LATINIME_DICT_TOOLKIT_DIFF_EXECUTOR_H #define LATINIME_DICT_TOOLKIT_DIFF_EXECUTOR_H
#include "dict_toolkit_defines.h" #include "dict_toolkit_defines.h"
#include "utils/arguments_parser.h"
namespace latinime { namespace latinime {
namespace dicttoolkit { namespace dicttoolkit {
@ -28,6 +29,7 @@ class DiffExecutor final {
static int run(const int argc, char **argv); static int run(const int argc, char **argv);
static void printUsage(); static void printUsage();
static const ArgumentsParser getArgumentsParser();
private: private:
DISALLOW_IMPLICIT_CONSTRUCTORS(DiffExecutor); DISALLOW_IMPLICIT_CONSTRUCTORS(DiffExecutor);

View File

@ -30,9 +30,19 @@ const char *const HeaderExecutor::COMMAND_NAME = "header";
/* static */ void HeaderExecutor::printUsage() { /* static */ void HeaderExecutor::printUsage() {
printf("*** %s\n", COMMAND_NAME); printf("*** %s\n", COMMAND_NAME);
printf("Usage: %s\n", COMMAND_NAME); getArgumentsParser().printUsage(COMMAND_NAME,
printf("Prints the header contents of a dictionary file.\n\n"); "Prints the header contents of a dictionary file.");
} }
/* static */ const ArgumentsParser HeaderExecutor::getArgumentsParser() {
std::unordered_map<std::string, OptionSpec> optionSpecs;
optionSpecs["p"] = OptionSpec::switchOption("(plumbing) produce output suitable for a script");
const std::vector<ArgumentSpec> argumentSpecs = {
ArgumentSpec::singleArgument("dict", "prints the header contents of a dictionary file")
};
return ArgumentsParser(std::move(optionSpecs), std::move(argumentSpecs));
}
} // namespace dicttoolkit } // namespace dicttoolkit
} // namespace latinime } // namespace latinime

View File

@ -18,6 +18,7 @@
#define LATINIME_DICT_TOOLKIT_HEADER_EXECUTOR_H #define LATINIME_DICT_TOOLKIT_HEADER_EXECUTOR_H
#include "dict_toolkit_defines.h" #include "dict_toolkit_defines.h"
#include "utils/arguments_parser.h"
namespace latinime { namespace latinime {
namespace dicttoolkit { namespace dicttoolkit {
@ -28,6 +29,7 @@ class HeaderExecutor final {
static int run(const int argc, char **argv); static int run(const int argc, char **argv);
static void printUsage(); static void printUsage();
static const ArgumentsParser getArgumentsParser();
private: private:
DISALLOW_IMPLICIT_CONSTRUCTORS(HeaderExecutor); DISALLOW_IMPLICIT_CONSTRUCTORS(HeaderExecutor);

View File

@ -17,6 +17,9 @@
#include "command_executors/info_executor.h" #include "command_executors/info_executor.h"
#include <cstdio> #include <cstdio>
#include <string>
#include <unordered_map>
#include <vector>
namespace latinime { namespace latinime {
namespace dicttoolkit { namespace dicttoolkit {
@ -30,8 +33,21 @@ const char *const InfoExecutor::COMMAND_NAME = "info";
/* static */ void InfoExecutor::printUsage() { /* static */ void InfoExecutor::printUsage() {
printf("*** %s\n", COMMAND_NAME); printf("*** %s\n", COMMAND_NAME);
printf("Usage: %s\n", COMMAND_NAME); getArgumentsParser().printUsage(COMMAND_NAME,
printf("Prints various information about a dictionary file.\n\n"); "Prints various information about a dictionary file.");
}
/* static */const ArgumentsParser InfoExecutor::getArgumentsParser() {
std::unordered_map<std::string, OptionSpec> optionSpecs;
optionSpecs["p"] = OptionSpec::switchOption("(plumbing) produce output suitable for a script");
const std::vector<ArgumentSpec> argumentSpecs = {
ArgumentSpec::singleArgument("dict", "dictionary file name"),
ArgumentSpec::variableLengthArguments("word", 0 /* minCount */,
ArgumentSpec::UNLIMITED_COUNT, "word to show information")
};
return ArgumentsParser(std::move(optionSpecs), std::move(argumentSpecs));
} }
} // namespace dicttoolkit } // namespace dicttoolkit

View File

@ -18,6 +18,7 @@
#define LATINIME_DICT_TOOLKIT_INFO_EXECUTOR_H #define LATINIME_DICT_TOOLKIT_INFO_EXECUTOR_H
#include "dict_toolkit_defines.h" #include "dict_toolkit_defines.h"
#include "utils/arguments_parser.h"
namespace latinime { namespace latinime {
namespace dicttoolkit { namespace dicttoolkit {
@ -28,6 +29,7 @@ class InfoExecutor final {
static int run(const int argc, char **argv); static int run(const int argc, char **argv);
static void printUsage(); static void printUsage();
static const ArgumentsParser getArgumentsParser();
private: private:
DISALLOW_IMPLICIT_CONSTRUCTORS(InfoExecutor); DISALLOW_IMPLICIT_CONSTRUCTORS(InfoExecutor);

View File

@ -30,10 +30,25 @@ const char *const MakedictExecutor::COMMAND_NAME = "makedict";
/* static */ void MakedictExecutor::printUsage() { /* static */ void MakedictExecutor::printUsage() {
printf("*** %s\n", COMMAND_NAME); printf("*** %s\n", COMMAND_NAME);
printf("Usage: %s\n", COMMAND_NAME); getArgumentsParser().printUsage(COMMAND_NAME,
printf("Converts a source dictionary file to one or several outputs.\n" "Converts a source dictionary file to one or several outputs.\n"
"Source can be a binary dictionary file or a combined format file.\n" "Source can be a binary dictionary file or a combined format file.\n"
"Binary version 2 (Jelly Bean), 4, and combined format outputs are supported.\n\n"); "Binary version 2 (Jelly Bean), 4, and combined format outputs are supported.");
}
/* static */const ArgumentsParser MakedictExecutor::getArgumentsParser() {
std::unordered_map<std::string, OptionSpec> optionSpecs;
optionSpecs["o"] = OptionSpec::keyValueOption("format", "2",
"output format version: 2/4/combined");
optionSpecs["t"] = OptionSpec::keyValueOption("mode", "off",
"code point table switch: on/off/auto");
const std::vector<ArgumentSpec> argumentSpecs = {
ArgumentSpec::singleArgument("src_dict", "source dictionary file"),
ArgumentSpec::singleArgument("dest_dict", "output dictionary file")
};
return ArgumentsParser(std::move(optionSpecs), std::move(argumentSpecs));
} }
} // namespace dicttoolkit } // namespace dicttoolkit

View File

@ -18,6 +18,7 @@
#define LATINIME_DICT_TOOLKIT_MAKEDICT_EXECUTOR_H #define LATINIME_DICT_TOOLKIT_MAKEDICT_EXECUTOR_H
#include "dict_toolkit_defines.h" #include "dict_toolkit_defines.h"
#include "utils/arguments_parser.h"
namespace latinime { namespace latinime {
namespace dicttoolkit { namespace dicttoolkit {
@ -28,6 +29,7 @@ class MakedictExecutor final {
static int run(const int argc, char **argv); static int run(const int argc, char **argv);
static void printUsage(); static void printUsage();
static const ArgumentsParser getArgumentsParser();
private: private:
DISALLOW_IMPLICIT_CONSTRUCTORS(MakedictExecutor); DISALLOW_IMPLICIT_CONSTRUCTORS(MakedictExecutor);

View File

@ -0,0 +1,54 @@
/*
* Copyright (C) 2014 The Android Open Source Project
*
* 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.
*/
#ifndef LATINIME_DICT_TOOLKIT_ARGUMENTS_AND_OPTIONS_H
#define LATINIME_DICT_TOOLKIT_ARGUMENTS_AND_OPTIONS_H
#include <string>
#include <unordered_map>
#include <vector>
#include "dict_toolkit_defines.h"
namespace latinime {
namespace dicttoolkit {
class ArgumentsAndOptions {
public:
ArgumentsAndOptions() : mIsValid(false), mOptions(), mArguments() {}
ArgumentsAndOptions(std::unordered_map<std::string, std::string> &&options,
std::unordered_map<std::string, std::vector<std::string>> &&arguments)
: mIsValid(true), mOptions(std::move(options)), mArguments(std::move(arguments)) {}
bool isValid() const {
return mIsValid;
}
bool hasOption(const std::string &optionName) const {
return mOptions.find(optionName) != mOptions.end();
}
private:
DISALLOW_ASSIGNMENT_OPERATOR(ArgumentsAndOptions);
const bool mIsValid;
const std::unordered_map<std::string, std::string> mOptions;
const std::unordered_map<std::string, std::vector<std::string>> mArguments;
};
} // namespace dicttoolkit
} // namespace latinime
#endif // LATINIME_DICT_TOOLKIT_ARGUMENTS_AND_OPTIONS_H

View File

@ -0,0 +1,84 @@
/*
* Copyright (C) 2014 The Android Open Source Project
*
* 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 "utils/arguments_parser.h"
namespace latinime {
namespace dicttoolkit {
const int ArgumentSpec::UNLIMITED_COUNT = -1;
bool ArgumentsParser::validateSpecs() const {
for (size_t i = 0; i < mArgumentSpecs.size() ; ++i) {
if (mArgumentSpecs[i].getMinCount() != mArgumentSpecs[i].getMaxCount()
&& i != mArgumentSpecs.size() - 1) {
AKLOGE("Variable length argument must be at the end.");
return false;
}
}
return true;
}
void ArgumentsParser::printUsage(const std::string &commandName,
const std::string &description) const {
printf("Usage: %s", commandName.c_str());
for (const auto &option : mOptionSpecs) {
const std::string &optionName = option.first;
const OptionSpec &spec = option.second;
printf(" [-%s", optionName.c_str());
if (spec.takeValue()) {
printf(" <%s>", spec.getValueName().c_str());
}
printf("]");
}
for (const auto &argSpec : mArgumentSpecs) {
if (argSpec.getMinCount() == 0 && argSpec.getMaxCount() == 1) {
printf(" [<%s>]", argSpec.getName().c_str());
} else if (argSpec.getMinCount() == 1 && argSpec.getMaxCount() == 1) {
printf(" <%s>", argSpec.getName().c_str());
} else if (argSpec.getMinCount() == 0) {
printf(" [<%s>...]", argSpec.getName().c_str());
} else if (argSpec.getMinCount() == 1) {
printf(" <%s>...", argSpec.getName().c_str());
}
}
printf("\n%s\n\n", description.c_str());
for (const auto &option : mOptionSpecs) {
const std::string &optionName = option.first;
const OptionSpec &spec = option.second;
printf(" -%s", optionName.c_str());
if (spec.takeValue()) {
printf(" <%s>", spec.getValueName().c_str());
}
printf("\t\t\t%s", spec.getDescription().c_str());
if (spec.takeValue() && !spec.getDefaultValue().empty()) {
printf("\tdefault: %s", spec.getDefaultValue().c_str());
}
printf("\n");
}
for (const auto &argSpec : mArgumentSpecs) {
printf(" <%s>\t\t\t%s\n", argSpec.getName().c_str(), argSpec.getDescription().c_str());
}
printf("\n\n");
}
const ArgumentsAndOptions ArgumentsParser::parseArguments(const int argc, char **argv) const {
// TODO: Implement
return ArgumentsAndOptions();
}
} // namespace dicttoolkit
} // namespace latinime

View File

@ -0,0 +1,118 @@
/*
* Copyright (C) 2014 The Android Open Source Project
*
* 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.
*/
#ifndef LATINIME_DICT_TOOLKIT_ARGUMENTS_PARSER_H
#define LATINIME_DICT_TOOLKIT_ARGUMENTS_PARSER_H
#include <string>
#include <unordered_map>
#include <vector>
#include "dict_toolkit_defines.h"
#include "utils/arguments_and_options.h"
namespace latinime {
namespace dicttoolkit {
class OptionSpec {
public:
// Default constructor and assignment operator is enabled to be used with std::unordered_map.
OptionSpec() = default;
OptionSpec &operator=(const OptionSpec &) = default;
static OptionSpec keyValueOption(const std::string &valueName, const std::string &defaultValue,
const std::string &description) {
return OptionSpec(true /* takeValue */, valueName, defaultValue, description);
}
static OptionSpec switchOption(const std::string &description) {
return OptionSpec(false /* takeValue */, "" /* valueName */, "" /* defaultValue */,
description);
}
bool takeValue() const { return mTakeValue; }
const std::string &getValueName() const { return mValueName; }
const std::string &getDefaultValue() const { return mDefaultValue; }
const std::string &getDescription() const { return mDescription; }
private:
OptionSpec(const bool takeValue, const std::string &valueName, const std::string &defaultValue,
const std::string &description)
: mTakeValue(takeValue), mValueName(valueName), mDefaultValue(defaultValue),
mDescription(description) {}
// Whether the option have to be used with a value or just a switch.
// e.g. 'f' in "command -f /path/to/file" is mTakeValue == true.
// 'f' in "command -f -t" is mTakeValue == false.
bool mTakeValue;
// Name of the value used to show usage.
std::string mValueName;
std::string mDefaultValue;
std::string mDescription;
};
class ArgumentSpec {
public:
static const int UNLIMITED_COUNT;
static ArgumentSpec singleArgument(const std::string &name, const std::string &description) {
return ArgumentSpec(name, 1 /* minCount */, 1 /* maxCount */, description);
}
static ArgumentSpec variableLengthArguments(const std::string &name, const int minCount,
const int maxCount, const std::string &description) {
return ArgumentSpec(name, minCount, maxCount, description);
}
const std::string &getName() const { return mName; }
int getMinCount() const { return mMinCount; }
int getMaxCount() const { return mMaxCount; }
const std::string &getDescription() const { return mDescription; }
private:
DISALLOW_DEFAULT_CONSTRUCTOR(ArgumentSpec);
ArgumentSpec(const std::string &name, const int minCount, const int maxCount,
const std::string &description)
: mName(name), mMinCount(minCount), mMaxCount(maxCount), mDescription(description) {}
const std::string mName;
const int mMinCount;
const int mMaxCount;
const std::string mDescription;
};
class ArgumentsParser {
public:
ArgumentsParser(std::unordered_map<std::string, OptionSpec> &&optionSpecs,
std::vector<ArgumentSpec> &&argumentSpecs)
: mOptionSpecs(std::move(optionSpecs)), mArgumentSpecs(std::move(argumentSpecs)) {}
const ArgumentsAndOptions parseArguments(const int argc, char **argv) const;
bool validateSpecs() const;
void printUsage(const std::string &commandName, const std::string &description) const;
private:
DISALLOW_DEFAULT_CONSTRUCTOR(ArgumentsParser);
DISALLOW_ASSIGNMENT_OPERATOR(ArgumentsParser);
const std::unordered_map<std::string, OptionSpec> mOptionSpecs;
const std::vector<ArgumentSpec> mArgumentSpecs;
};
} // namespace dicttoolkit
} // namespace latinime
#endif // LATINIME_DICT_TOOLKIT_ARGUMENTS_PARSER_H

View File

@ -0,0 +1,31 @@
/*
* Copyright (C) 2014 The Android Open Source Project
*
* 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 "command_executors/diff_executor.h"
#include <gtest/gtest.h>
namespace latinime {
namespace dicttoolkit {
namespace {
TEST(DiffExecutorTests, TestArguemntSpecs) {
EXPECT_TRUE(DiffExecutor::getArgumentsParser().validateSpecs());
}
} // namespace
} // namespace dicttoolkit
} // namespace latinime

View File

@ -0,0 +1,31 @@
/*
* Copyright (C) 2014 The Android Open Source Project
*
* 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 "command_executors/header_executor.h"
#include <gtest/gtest.h>
namespace latinime {
namespace dicttoolkit {
namespace {
TEST(HeaderExecutorTests, TestArguemntSpecs) {
EXPECT_TRUE(HeaderExecutor::getArgumentsParser().validateSpecs());
}
} // namespace
} // namespace dicttoolkit
} // namespace latinime

View File

@ -0,0 +1,31 @@
/*
* Copyright (C) 2014 The Android Open Source Project
*
* 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 "command_executors/info_executor.h"
#include <gtest/gtest.h>
namespace latinime {
namespace dicttoolkit {
namespace {
TEST(InfoExecutorTests, TestArguemntSpecs) {
EXPECT_TRUE(InfoExecutor::getArgumentsParser().validateSpecs());
}
} // namespace
} // namespace dicttoolkit
} // namespace latinime

View File

@ -0,0 +1,31 @@
/*
* Copyright (C) 2014 The Android Open Source Project
*
* 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 "command_executors/makedict_executor.h"
#include <gtest/gtest.h>
namespace latinime {
namespace dicttoolkit {
namespace {
TEST(MakedictExecutorTests, TestArguemntSpecs) {
EXPECT_TRUE(MakedictExecutor::getArgumentsParser().validateSpecs());
}
} // namespace
} // namespace dicttoolkit
} // namespace latinime