1*eca53ba6SRoland Levillain// Copyright 2017 Google LLC 2*eca53ba6SRoland Levillain// 3*eca53ba6SRoland Levillain// Licensed under the Apache License, Version 2.0 (the "License"); 4*eca53ba6SRoland Levillain// you may not use this file except in compliance with the License. 5*eca53ba6SRoland Levillain// You may obtain a copy of the License at 6*eca53ba6SRoland Levillain// 7*eca53ba6SRoland Levillain// http://www.apache.org/licenses/LICENSE-2.0 8*eca53ba6SRoland Levillain// 9*eca53ba6SRoland Levillain// Unless required by applicable law or agreed to in writing, software 10*eca53ba6SRoland Levillain// distributed under the License is distributed on an "AS IS" BASIS, 11*eca53ba6SRoland Levillain// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*eca53ba6SRoland Levillain// See the License for the specific language governing permissions and 13*eca53ba6SRoland Levillain// limitations under the License. 14*eca53ba6SRoland Levillain 15*eca53ba6SRoland Levillain#ifndef INTROSPECTION_PREFIX 16*eca53ba6SRoland Levillain#error "missing INTROSPECTION_PREFIX" 17*eca53ba6SRoland Levillain#endif 18*eca53ba6SRoland Levillain#ifndef INTROSPECTION_ENUM_PREFIX 19*eca53ba6SRoland Levillain#error "missing INTROSPECTION_ENUM_PREFIX" 20*eca53ba6SRoland Levillain#endif 21*eca53ba6SRoland Levillain#ifndef INTROSPECTION_TABLE 22*eca53ba6SRoland Levillain#error "missing INTROSPECTION_TABLE" 23*eca53ba6SRoland Levillain#endif 24*eca53ba6SRoland Levillain 25*eca53ba6SRoland Levillain#include <stdbool.h> 26*eca53ba6SRoland Levillain 27*eca53ba6SRoland Levillain#define STRINGIZE_(s) #s 28*eca53ba6SRoland Levillain#define STRINGIZE(s) STRINGIZE_(s) 29*eca53ba6SRoland Levillain 30*eca53ba6SRoland Levillain#define FEAT_TYPE_NAME__(X) X##Features 31*eca53ba6SRoland Levillain#define FEAT_TYPE_NAME_(X) FEAT_TYPE_NAME__(X) 32*eca53ba6SRoland Levillain#define FEAT_TYPE_NAME FEAT_TYPE_NAME_(INTROSPECTION_PREFIX) 33*eca53ba6SRoland Levillain 34*eca53ba6SRoland Levillain#define FEAT_ENUM_NAME__(X) X##FeaturesEnum 35*eca53ba6SRoland Levillain#define FEAT_ENUM_NAME_(X) FEAT_ENUM_NAME__(X) 36*eca53ba6SRoland Levillain#define FEAT_ENUM_NAME FEAT_ENUM_NAME_(INTROSPECTION_PREFIX) 37*eca53ba6SRoland Levillain 38*eca53ba6SRoland Levillain#define GET_FEAT_ENUM_VALUE__(X) Get##X##FeaturesEnumValue 39*eca53ba6SRoland Levillain#define GET_FEAT_ENUM_VALUE_(X) GET_FEAT_ENUM_VALUE__(X) 40*eca53ba6SRoland Levillain#define GET_FEAT_ENUM_VALUE GET_FEAT_ENUM_VALUE_(INTROSPECTION_PREFIX) 41*eca53ba6SRoland Levillain 42*eca53ba6SRoland Levillain#define GET_FEAT_ENUM_NAME__(X) Get##X##FeaturesEnumName 43*eca53ba6SRoland Levillain#define GET_FEAT_ENUM_NAME_(X) GET_FEAT_ENUM_NAME__(X) 44*eca53ba6SRoland Levillain#define GET_FEAT_ENUM_NAME GET_FEAT_ENUM_NAME_(INTROSPECTION_PREFIX) 45*eca53ba6SRoland Levillain 46*eca53ba6SRoland Levillain#define FEAT_ENUM_LAST__(X) X##_LAST_ 47*eca53ba6SRoland Levillain#define FEAT_ENUM_LAST_(X) FEAT_ENUM_LAST__(X) 48*eca53ba6SRoland Levillain#define FEAT_ENUM_LAST FEAT_ENUM_LAST_(INTROSPECTION_ENUM_PREFIX) 49*eca53ba6SRoland Levillain 50*eca53ba6SRoland Levillain// Generate individual getters and setters. 51*eca53ba6SRoland Levillain#define LINE(ENUM, NAME, A, B, C) \ 52*eca53ba6SRoland Levillain static void set_##ENUM(FEAT_TYPE_NAME* features, bool value) { \ 53*eca53ba6SRoland Levillain features->NAME = value; \ 54*eca53ba6SRoland Levillain } \ 55*eca53ba6SRoland Levillain static int get_##ENUM(const FEAT_TYPE_NAME* features) { \ 56*eca53ba6SRoland Levillain return features->NAME; \ 57*eca53ba6SRoland Levillain } 58*eca53ba6SRoland LevillainINTROSPECTION_TABLE 59*eca53ba6SRoland Levillain#undef LINE 60*eca53ba6SRoland Levillain 61*eca53ba6SRoland Levillain// Generate getters table 62*eca53ba6SRoland Levillain#define LINE(ENUM, NAME, A, B, C) [ENUM] = get_##ENUM, 63*eca53ba6SRoland Levillainstatic int (*const kGetters[])(const FEAT_TYPE_NAME*) = {INTROSPECTION_TABLE}; 64*eca53ba6SRoland Levillain#undef LINE 65*eca53ba6SRoland Levillain 66*eca53ba6SRoland Levillain// Generate setters table 67*eca53ba6SRoland Levillain#define LINE(ENUM, NAME, A, B, C) [ENUM] = set_##ENUM, 68*eca53ba6SRoland Levillainstatic void (*const kSetters[])(FEAT_TYPE_NAME*, bool) = {INTROSPECTION_TABLE}; 69*eca53ba6SRoland Levillain#undef LINE 70*eca53ba6SRoland Levillain 71*eca53ba6SRoland Levillain// Implements the `GetXXXFeaturesEnumValue` API. 72*eca53ba6SRoland Levillainint GET_FEAT_ENUM_VALUE(const FEAT_TYPE_NAME* features, FEAT_ENUM_NAME value) { 73*eca53ba6SRoland Levillain if (value >= FEAT_ENUM_LAST) return false; 74*eca53ba6SRoland Levillain return kGetters[value](features); 75*eca53ba6SRoland Levillain} 76*eca53ba6SRoland Levillain 77*eca53ba6SRoland Levillain// Generate feature name table. 78*eca53ba6SRoland Levillain#define LINE(ENUM, NAME, A, B, C) [ENUM] = STRINGIZE(NAME), 79*eca53ba6SRoland Levillainstatic const char* kFeatureNames[] = {INTROSPECTION_TABLE}; 80*eca53ba6SRoland Levillain#undef LINE 81*eca53ba6SRoland Levillain 82*eca53ba6SRoland Levillain// Implements the `GetXXXFeaturesEnumName` API. 83*eca53ba6SRoland Levillainconst char* GET_FEAT_ENUM_NAME(FEAT_ENUM_NAME value) { 84*eca53ba6SRoland Levillain if (value >= FEAT_ENUM_LAST) return "unknown_feature"; 85*eca53ba6SRoland Levillain return kFeatureNames[value]; 86*eca53ba6SRoland Levillain} 87