1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef LATINIME_DICT_TOOLKIT_ARGUMENTS_PARSER_H 18 #define LATINIME_DICT_TOOLKIT_ARGUMENTS_PARSER_H 19 20 #include <string> 21 #include <unordered_map> 22 #include <vector> 23 24 #include "dict_toolkit_defines.h" 25 #include "utils/arguments_and_options.h" 26 27 namespace latinime { 28 namespace dicttoolkit { 29 30 class OptionSpec { 31 public: 32 // Default constructor and assignment operator is enabled to be used with std::unordered_map. 33 OptionSpec() = default; 34 OptionSpec &operator=(const OptionSpec &) = default; 35 keyValueOption(const std::string & valueName,const std::string & defaultValue,const std::string & description)36 static OptionSpec keyValueOption(const std::string &valueName, const std::string &defaultValue, 37 const std::string &description) { 38 return OptionSpec(true /* needsValue */, valueName, defaultValue, description); 39 } 40 switchOption(const std::string & description)41 static OptionSpec switchOption(const std::string &description) { 42 return OptionSpec(false /* needsValue */, "" /* valueName */, "" /* defaultValue */, 43 description); 44 } 45 needsValue()46 bool needsValue() const { return mNeedsValue; } getValueName()47 const std::string &getValueName() const { return mValueName; } getDefaultValue()48 const std::string &getDefaultValue() const { return mDefaultValue; } getDescription()49 const std::string &getDescription() const { return mDescription; } 50 51 private: OptionSpec(const bool needsValue,const std::string & valueName,const std::string & defaultValue,const std::string & description)52 OptionSpec(const bool needsValue, const std::string &valueName, const std::string &defaultValue, 53 const std::string &description) 54 : mNeedsValue(needsValue), mValueName(valueName), mDefaultValue(defaultValue), 55 mDescription(description) {} 56 57 // Whether the option have to be used with a value or just a switch. 58 // e.g. 'f' in "command -f /path/to/file" is mNeedsValue == true. 59 // 'f' in "command -f -t" is mNeedsValue == false. 60 bool mNeedsValue; 61 // Name of the value used to show usage. 62 std::string mValueName; 63 std::string mDefaultValue; 64 std::string mDescription; 65 }; 66 67 class ArgumentSpec { 68 public: 69 static const size_t UNLIMITED_COUNT; 70 singleArgument(const std::string & name,const std::string & description)71 static ArgumentSpec singleArgument(const std::string &name, const std::string &description) { 72 return ArgumentSpec(name, 1 /* minCount */, 1 /* maxCount */, description); 73 } 74 variableLengthArguments(const std::string & name,const size_t minCount,const size_t maxCount,const std::string & description)75 static ArgumentSpec variableLengthArguments(const std::string &name, const size_t minCount, 76 const size_t maxCount, const std::string &description) { 77 return ArgumentSpec(name, minCount, maxCount, description); 78 } 79 getName()80 const std::string &getName() const { return mName; } getMinCount()81 size_t getMinCount() const { return mMinCount; } getMaxCount()82 size_t getMaxCount() const { return mMaxCount; } getDescription()83 const std::string &getDescription() const { return mDescription; } 84 85 private: 86 DISALLOW_DEFAULT_CONSTRUCTOR(ArgumentSpec); 87 ArgumentSpec(const std::string & name,const size_t minCount,const size_t maxCount,const std::string & description)88 ArgumentSpec(const std::string &name, const size_t minCount, const size_t maxCount, 89 const std::string &description) 90 : mName(name), mMinCount(minCount), mMaxCount(maxCount), mDescription(description) {} 91 92 const std::string mName; 93 const size_t mMinCount; 94 const size_t mMaxCount; 95 const std::string mDescription; 96 }; 97 98 class ArgumentsParser { 99 public: ArgumentsParser(const std::unordered_map<std::string,OptionSpec> && optionSpecs,const std::vector<ArgumentSpec> && argumentSpecs)100 ArgumentsParser(const std::unordered_map<std::string, OptionSpec> &&optionSpecs, 101 const std::vector<ArgumentSpec> &&argumentSpecs) 102 : mOptionSpecs(std::move(optionSpecs)), mArgumentSpecs(std::move(argumentSpecs)) {} 103 104 const ArgumentsAndOptions parseArguments(const int argc, char **argv, 105 const bool printErrorMessage) const; 106 bool validateSpecs() const; 107 void printUsage(const std::string &commandName, const std::string &description) const; 108 109 private: 110 DISALLOW_DEFAULT_CONSTRUCTOR(ArgumentsParser); 111 DISALLOW_ASSIGNMENT_OPERATOR(ArgumentsParser); 112 113 const std::unordered_map<std::string, OptionSpec> mOptionSpecs; 114 const std::vector<ArgumentSpec> mArgumentSpecs; 115 }; 116 117 } // namespace dicttoolkit 118 } // namespace latinime 119 #endif // LATINIME_DICT_TOOLKIT_ARGUMENTS_PARSER_H 120