keyword_map.h 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /*
  2. * Copyright (C) 2015 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. #ifndef _INIT_KEYWORD_MAP_H_
  17. #define _INIT_KEYWORD_MAP_H_
  18. #include <map>
  19. #include <string>
  20. #include <android-base/stringprintf.h>
  21. #include "result.h"
  22. namespace android {
  23. namespace init {
  24. template <typename Function>
  25. class KeywordMap {
  26. public:
  27. using FunctionInfo = std::tuple<std::size_t, std::size_t, Function>;
  28. using Map = std::map<std::string, FunctionInfo>;
  29. virtual ~KeywordMap() {
  30. }
  31. const Result<Function> FindFunction(const std::vector<std::string>& args) const {
  32. using android::base::StringPrintf;
  33. if (args.empty()) return Error() << "Keyword needed, but not provided";
  34. auto& keyword = args[0];
  35. auto num_args = args.size() - 1;
  36. auto function_info_it = map().find(keyword);
  37. if (function_info_it == map().end()) {
  38. return Error() << StringPrintf("Invalid keyword '%s'", keyword.c_str());
  39. }
  40. auto function_info = function_info_it->second;
  41. auto min_args = std::get<0>(function_info);
  42. auto max_args = std::get<1>(function_info);
  43. if (min_args == max_args && num_args != min_args) {
  44. return Error() << StringPrintf("%s requires %zu argument%s", keyword.c_str(), min_args,
  45. (min_args > 1 || min_args == 0) ? "s" : "");
  46. }
  47. if (num_args < min_args || num_args > max_args) {
  48. if (max_args == std::numeric_limits<decltype(max_args)>::max()) {
  49. return Error() << StringPrintf("%s requires at least %zu argument%s",
  50. keyword.c_str(), min_args, min_args > 1 ? "s" : "");
  51. } else {
  52. return Error() << StringPrintf("%s requires between %zu and %zu arguments",
  53. keyword.c_str(), min_args, max_args);
  54. }
  55. }
  56. return std::get<Function>(function_info);
  57. }
  58. private:
  59. // Map of keyword ->
  60. // (minimum number of arguments, maximum number of arguments, function pointer)
  61. virtual const Map& map() const = 0;
  62. };
  63. } // namespace init
  64. } // namespace android
  65. #endif