1 /* Copyright 2018 The TensorFlow Authors. All Rights Reserved. 2 3 Licensed under the Apache License, Version 2.0 (the "License"); 4 you may not use this file except in compliance with the License. 5 You may obtain a copy of the License at 6 7 http://www.apache.org/licenses/LICENSE-2.0 8 9 Unless required by applicable law or agreed to in writing, software 10 distributed under the License is distributed on an "AS IS" BASIS, 11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 See the License for the specific language governing permissions and 13 limitations under the License. 14 ==============================================================================*/ 15 #include "tensorflow/contrib/lite/schema/builtin_ops_header/generator.h" 16 #include "tensorflow/contrib/lite/schema/schema_generated.h" 17 18 namespace tflite { 19 namespace builtin_ops_header { 20 21 namespace { 22 const char* kFileHeader = 23 R"(/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. 24 25 Licensed under the Apache License, Version 2.0 (the "License"); 26 you may not use this file except in compliance with the License. 27 You may obtain a copy of the License at 28 29 http://www.apache.org/licenses/LICENSE-2.0 30 31 Unless required by applicable law or agreed to in writing, software 32 distributed under the License is distributed on an "AS IS" BASIS, 33 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 34 See the License for the specific language governing permissions and 35 limitations under the License. 36 ==============================================================================*/ 37 38 #ifndef TENSORFLOW_CONTRIB_LITE_BUILTIN_OPS_H_ 39 #define TENSORFLOW_CONTRIB_LITE_BUILTIN_OPS_H_ 40 41 // DO NOT EDIT MANUALLY: This file is automatically generated by 42 // `schema_builtin_ops_header_generator.py`. 43 44 #ifdef __cplusplus 45 extern "C" { 46 #endif // __cplusplus 47 48 typedef enum { 49 )"; 50 51 const char* kFileFooter = 52 R"(} TfLiteBuiltinOperator; 53 54 #ifdef __cplusplus 55 } // extern "C" 56 #endif // __cplusplus 57 #endif // TENSORFLOW_CONTRIB_LITE_BUILTIN_OPS_H_ 58 } 59 )"; 60 } // anonymous namespace 61 62 bool IsValidInputEnumName(const std::string& name) { 63 const char* begin = name.c_str(); 64 const char* ch = begin; 65 while (*ch != '\0') { 66 // If it's not the first character, expect an underscore. 67 if (ch != begin) { 68 if (*ch != '_') { 69 return false; 70 } 71 ++ch; 72 } 73 74 // Expecting a word with upper case letters or digits, like "CONV", 75 // "CONV2D", "2D"...etc. 76 bool empty = true; 77 while (isupper(*ch) || isdigit(*ch)) { 78 // It's not empty if at least one character is consumed. 79 empty = false; 80 ++ch; 81 } 82 if (empty) { 83 return false; 84 } 85 } 86 return true; 87 } 88 89 std::string ConstantizeVariableName(const std::string& name) { 90 std::string result = "kTfLiteBuiltin"; 91 bool uppercase = true; 92 for (char input_char : name) { 93 if (input_char == '_') { 94 uppercase = true; 95 } else if (uppercase) { 96 result += toupper(input_char); 97 uppercase = false; 98 } else { 99 result += tolower(input_char); 100 } 101 } 102 103 return result; 104 } 105 106 bool GenerateHeader(std::ostream& os) { 107 auto enum_names = tflite::EnumNamesBuiltinOperator(); 108 109 // Check if all the input enum names are valid. 110 for (auto enum_value : EnumValuesBuiltinOperator()) { 111 auto enum_name = enum_names[enum_value]; 112 if (!IsValidInputEnumName(enum_name)) { 113 std::cerr << "Invalid input enum name: " << enum_name << std::endl; 114 return false; 115 } 116 } 117 118 os << kFileHeader; 119 for (auto enum_value : EnumValuesBuiltinOperator()) { 120 auto enum_name = enum_names[enum_value]; 121 os << " "; 122 os << ConstantizeVariableName(enum_name); 123 os << " = "; 124 os << enum_value; 125 os << ",\n"; 126 } 127 os << kFileFooter; 128 return true; 129 } 130 131 } // namespace builtin_ops_header 132 } // namespace tflite 133