Home | History | Annotate | Download | only in init
      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 
     17 #ifndef _INIT_KEYWORD_MAP_H_
     18 #define _INIT_KEYWORD_MAP_H_
     19 
     20 #include <map>
     21 #include <string>
     22 
     23 #include <android-base/stringprintf.h>
     24 
     25 template <typename Function>
     26 class KeywordMap {
     27 public:
     28     using FunctionInfo = std::tuple<std::size_t, std::size_t, Function>;
     29     using Map = const std::map<std::string, FunctionInfo>;
     30 
     31     virtual ~KeywordMap() {
     32     }
     33 
     34     const Function FindFunction(const std::string& keyword,
     35                                 size_t num_args,
     36                                 std::string* err) const {
     37         using android::base::StringPrintf;
     38 
     39         auto function_info_it = map().find(keyword);
     40         if (function_info_it == map().end()) {
     41             *err = StringPrintf("invalid keyword '%s'", keyword.c_str());
     42             return nullptr;
     43         }
     44 
     45         auto function_info = function_info_it->second;
     46 
     47         auto min_args = std::get<0>(function_info);
     48         auto max_args = std::get<1>(function_info);
     49         if (min_args == max_args && num_args != min_args) {
     50             *err = StringPrintf("%s requires %zu argument%s",
     51                                 keyword.c_str(), min_args,
     52                                 (min_args > 1 || min_args == 0) ? "s" : "");
     53             return nullptr;
     54         }
     55 
     56         if (num_args < min_args || num_args > max_args) {
     57             if (max_args == std::numeric_limits<decltype(max_args)>::max()) {
     58                 *err = StringPrintf("%s requires at least %zu argument%s",
     59                                     keyword.c_str(), min_args,
     60                                     min_args > 1 ? "s" : "");
     61             } else {
     62                 *err = StringPrintf("%s requires between %zu and %zu arguments",
     63                                     keyword.c_str(), min_args, max_args);
     64             }
     65             return nullptr;
     66         }
     67 
     68         return std::get<Function>(function_info);
     69     }
     70 
     71 private:
     72 //Map of keyword ->
     73 //(minimum number of arguments, maximum number of arguments, function pointer)
     74     virtual Map& map() const = 0;
     75 };
     76 
     77 #endif
     78