179273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi/*
279273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi * Copyright (C) 2014 The Android Open Source Project
379273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi *
479273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi * Licensed under the Apache License, Version 2.0 (the "License");
579273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi * you may not use this file except in compliance with the License.
679273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi * You may obtain a copy of the License at
779273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi *
879273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi *      http://www.apache.org/licenses/LICENSE-2.0
979273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi *
1079273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi * Unless required by applicable law or agreed to in writing, software
1179273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi * distributed under the License is distributed on an "AS IS" BASIS,
1279273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1379273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi * See the License for the specific language governing permissions and
1479273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi * limitations under the License.
1579273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi */
1679273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi
1779273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi#ifndef LATINIME_DICT_TOOLKIT_ARGUMENTS_PARSER_H
1879273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi#define LATINIME_DICT_TOOLKIT_ARGUMENTS_PARSER_H
1979273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi
2079273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi#include <string>
2179273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi#include <unordered_map>
2279273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi#include <vector>
2379273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi
2479273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi#include "dict_toolkit_defines.h"
2579273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi#include "utils/arguments_and_options.h"
2679273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi
2779273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanaginamespace latinime {
2879273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanaginamespace dicttoolkit {
2979273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi
3079273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagiclass OptionSpec {
3179273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi public:
3279273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi    // Default constructor and assignment operator is enabled to be used with std::unordered_map.
3379273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi    OptionSpec() = default;
3479273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi    OptionSpec &operator=(const OptionSpec &) = default;
3579273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi
3679273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi    static OptionSpec keyValueOption(const std::string &valueName, const std::string &defaultValue,
3779273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi            const std::string &description) {
381f8d4f47e445bd4316f3e09228cff6de64105f13Keisuke Kuroyanagi        return OptionSpec(true /* needsValue */, valueName, defaultValue, description);
3979273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi    }
4079273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi
4179273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi    static OptionSpec switchOption(const std::string &description) {
421f8d4f47e445bd4316f3e09228cff6de64105f13Keisuke Kuroyanagi        return OptionSpec(false /* needsValue */, "" /* valueName */, "" /* defaultValue */,
4379273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi                description);
4479273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi    }
4579273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi
461f8d4f47e445bd4316f3e09228cff6de64105f13Keisuke Kuroyanagi    bool needsValue() const { return mNeedsValue; }
4779273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi    const std::string &getValueName() const { return mValueName; }
4879273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi    const std::string &getDefaultValue() const { return mDefaultValue; }
4979273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi    const std::string &getDescription() const { return mDescription; }
5079273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi
5179273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi private:
521f8d4f47e445bd4316f3e09228cff6de64105f13Keisuke Kuroyanagi    OptionSpec(const bool needsValue, const std::string &valueName, const std::string &defaultValue,
5379273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi            const std::string &description)
541f8d4f47e445bd4316f3e09228cff6de64105f13Keisuke Kuroyanagi            : mNeedsValue(needsValue), mValueName(valueName), mDefaultValue(defaultValue),
5579273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi              mDescription(description) {}
5679273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi
5779273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi    // Whether the option have to be used with a value or just a switch.
581f8d4f47e445bd4316f3e09228cff6de64105f13Keisuke Kuroyanagi    // e.g. 'f' in "command -f /path/to/file" is mNeedsValue == true.
591f8d4f47e445bd4316f3e09228cff6de64105f13Keisuke Kuroyanagi    //      'f' in "command -f -t" is mNeedsValue == false.
601f8d4f47e445bd4316f3e09228cff6de64105f13Keisuke Kuroyanagi    bool mNeedsValue;
6179273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi    // Name of the value used to show usage.
6279273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi    std::string mValueName;
6379273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi    std::string mDefaultValue;
6479273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi    std::string mDescription;
6579273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi};
6679273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi
6779273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagiclass ArgumentSpec {
6879273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi public:
691f8d4f47e445bd4316f3e09228cff6de64105f13Keisuke Kuroyanagi    static const size_t UNLIMITED_COUNT;
7079273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi
7179273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi    static ArgumentSpec singleArgument(const std::string &name, const std::string &description) {
7279273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi        return ArgumentSpec(name, 1 /* minCount */, 1 /* maxCount */, description);
7379273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi    }
7479273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi
751f8d4f47e445bd4316f3e09228cff6de64105f13Keisuke Kuroyanagi    static ArgumentSpec variableLengthArguments(const std::string &name, const size_t minCount,
761f8d4f47e445bd4316f3e09228cff6de64105f13Keisuke Kuroyanagi            const size_t maxCount, const std::string &description) {
7779273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi        return ArgumentSpec(name, minCount, maxCount, description);
7879273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi    }
7979273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi
8079273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi    const std::string &getName() const { return mName; }
811f8d4f47e445bd4316f3e09228cff6de64105f13Keisuke Kuroyanagi    size_t getMinCount() const { return mMinCount; }
821f8d4f47e445bd4316f3e09228cff6de64105f13Keisuke Kuroyanagi    size_t getMaxCount() const { return mMaxCount; }
8379273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi    const std::string &getDescription() const { return mDescription; }
8479273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi
8579273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi private:
8679273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi    DISALLOW_DEFAULT_CONSTRUCTOR(ArgumentSpec);
8779273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi
881f8d4f47e445bd4316f3e09228cff6de64105f13Keisuke Kuroyanagi    ArgumentSpec(const std::string &name, const size_t minCount, const size_t maxCount,
8979273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi            const std::string &description)
9079273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi            : mName(name), mMinCount(minCount), mMaxCount(maxCount), mDescription(description) {}
9179273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi
9279273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi    const std::string mName;
931f8d4f47e445bd4316f3e09228cff6de64105f13Keisuke Kuroyanagi    const size_t mMinCount;
941f8d4f47e445bd4316f3e09228cff6de64105f13Keisuke Kuroyanagi    const size_t mMaxCount;
9579273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi    const std::string mDescription;
9679273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi};
9779273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi
9879273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagiclass ArgumentsParser {
9979273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi public:
100681dbc295b07b9db6c32d1b7074e99d9e2fa651dKeisuke Kuroyanagi    ArgumentsParser(const std::unordered_map<std::string, OptionSpec> &&optionSpecs,
101681dbc295b07b9db6c32d1b7074e99d9e2fa651dKeisuke Kuroyanagi            const std::vector<ArgumentSpec> &&argumentSpecs)
10279273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi            : mOptionSpecs(std::move(optionSpecs)), mArgumentSpecs(std::move(argumentSpecs)) {}
10379273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi
1041f8d4f47e445bd4316f3e09228cff6de64105f13Keisuke Kuroyanagi    const ArgumentsAndOptions parseArguments(const int argc, char **argv,
1051f8d4f47e445bd4316f3e09228cff6de64105f13Keisuke Kuroyanagi            const bool printErrorMessage) const;
10679273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi    bool validateSpecs() const;
10779273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi    void printUsage(const std::string &commandName, const std::string &description) const;
10879273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi
10979273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi private:
11079273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi    DISALLOW_DEFAULT_CONSTRUCTOR(ArgumentsParser);
11179273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi    DISALLOW_ASSIGNMENT_OPERATOR(ArgumentsParser);
11279273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi
11379273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi    const std::unordered_map<std::string, OptionSpec> mOptionSpecs;
11479273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi    const std::vector<ArgumentSpec> mArgumentSpecs;
11579273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi};
11679273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi
11779273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi} // namespace dicttoolkit
11879273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi} // namespace latinime
11979273b04772824a8c547e1a8d33900040a03264bKeisuke Kuroyanagi#endif // LATINIME_DICT_TOOLKIT_ARGUMENTS_PARSER_H
120