keunyoung | 15882e5 | 2015-09-16 16:57:58 -0700 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | # |
| 3 | # Copyright (C) 2015 The Android Open Source Project |
| 4 | # |
| 5 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | # you may not use this file except in compliance with the License. |
| 7 | # You may obtain a copy of the License at |
| 8 | # |
| 9 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | # |
| 11 | # Unless required by applicable law or agreed to in writing, software |
| 12 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | # See the License for the specific language governing permissions and |
| 15 | # limitations under the License. |
| 16 | # |
| 17 | """Generate Java code from vehicle.h""" |
| 18 | import os |
| 19 | import re |
| 20 | import sys |
| 21 | |
| 22 | JAVA_HEADER = \ |
| 23 | """ |
| 24 | /* |
| 25 | * Copyright (C) 2015 The Android Open Source Project |
| 26 | * |
| 27 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 28 | * you may not use this file except in compliance with the License. |
| 29 | * You may obtain a copy of the License at |
| 30 | * |
| 31 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 32 | * |
| 33 | * Unless required by applicable law or agreed to in writing, software |
| 34 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 35 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 36 | * See the License for the specific language governing permissions and |
| 37 | * limitations under the License. |
| 38 | */ |
| 39 | |
Vitalii Tomkiv | 5f537ee | 2016-10-11 14:26:44 -0700 | [diff] [blame] | 40 | // Autogenerated from vehicle.h using |
| 41 | // libvehiclenetwork/tool/vehiclehal_code_gen.py. |
| 42 | // Do not modify manually. |
keunyoung | 15882e5 | 2015-09-16 16:57:58 -0700 | [diff] [blame] | 43 | |
| 44 | package com.android.car.vehiclenetwork; |
| 45 | |
| 46 | public class VehicleNetworkConsts { |
| 47 | """ |
| 48 | |
| 49 | JAVA_TRAIL = \ |
| 50 | """ |
| 51 | } |
| 52 | """ |
| 53 | |
Vitalii Tomkiv | 5f537ee | 2016-10-11 14:26:44 -0700 | [diff] [blame] | 54 | RE_PROPERTY_PATTERN = r'/\*\*((.(?!\/\/===))*?)\*/\n\#define\s+VEHICLE_PROPERTY_(\S+)\s+(\(0x\S+\))' |
keunyoung | 15882e5 | 2015-09-16 16:57:58 -0700 | [diff] [blame] | 55 | RE_ENUM_PATTERN = r'enum\s+(\S+)\s+\{\S*(.*?)\}' |
keunyoung | 38ba530 | 2015-10-14 13:50:21 -0700 | [diff] [blame] | 56 | RE_ENUM_ENTRY_PATTERN = r'(\S+)\s*=\s*(.*?)[,\n]' |
Keun-young Park | 4c6834a | 2016-06-28 12:58:23 -0700 | [diff] [blame] | 57 | RE_AUDIO_EXT_ROUTING_PATTERN = r'\n\#define\s+VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_SOURCE_(\S+)\s+\"(\S+)\"' |
keunyoung | 15882e5 | 2015-09-16 16:57:58 -0700 | [diff] [blame] | 58 | |
| 59 | class PropertyInfo(object): |
| 60 | def __init__(self, value, name): |
| 61 | self.value = value |
| 62 | self.name = name |
| 63 | self.type = "" |
| 64 | self.changeMode = "" |
| 65 | self.access = "" |
| 66 | self.unit = "" |
keunyoung | d32f4e6 | 2015-09-21 11:33:06 -0700 | [diff] [blame] | 67 | self.startEnd = 0 # _START/END property |
Vitalii Tomkiv | 5f537ee | 2016-10-11 14:26:44 -0700 | [diff] [blame] | 68 | self.zoneType = "" |
keunyoung | 15882e5 | 2015-09-16 16:57:58 -0700 | [diff] [blame] | 69 | |
| 70 | def __str__(self): |
| 71 | r = ["value:" + self.value] |
| 72 | r.append("name:" + self.name) |
| 73 | if self.type != "": |
| 74 | r.append("type:" + self.type) |
| 75 | if self.changeMode != "": |
| 76 | r.append("changeMode:" + self.changeMode) |
| 77 | if self.access != "": |
| 78 | r.append("access:" + self.access) |
| 79 | if self.unit != "": |
| 80 | r.append("unit:" + self.unit) |
| 81 | return " ".join(r) |
| 82 | |
| 83 | class EnumInfo(object): |
| 84 | def __init__(self, name): |
| 85 | self.name = name |
| 86 | self.enums = [] #(name, value) tuple |
| 87 | def addEntry(self, name, value): |
| 88 | self.enums.append((name, value)) |
| 89 | def __str__(self): |
| 90 | r = [self.name + "\n"] |
| 91 | for e in self.enums: |
| 92 | r.append(" " + e[0] + ":" + e[1] + "\n") |
| 93 | return ''.join(r) |
| 94 | |
| 95 | def toJavaStyleName(name): |
| 96 | # do not convert if 1st letter is already upper |
| 97 | if name[0].isupper(): |
| 98 | return name |
| 99 | words = name.split("_") |
| 100 | #print words |
| 101 | for i in range(len(words)): |
| 102 | w = words[i] |
| 103 | w = w[0].upper() + w[1:] |
| 104 | words[i] = w |
| 105 | return ''.join(words) |
| 106 | |
| 107 | JAVA_INT_DEF = "public static final int " |
| 108 | def printProperties(props): |
| 109 | for p in props: |
| 110 | print JAVA_INT_DEF + p.name + " = " + p.value + ";" |
| 111 | |
| 112 | #now impement getVehicleValueType |
| 113 | print \ |
| 114 | """public static int getVehicleValueType(int property) { |
| 115 | switch (property) {""" |
| 116 | for p in props: |
| 117 | if p.type != "": |
| 118 | print "case " + p.name + ": return VehicleValueType." + p.type + ";" |
| 119 | print \ |
| 120 | """default: return VehicleValueType.VEHICLE_VALUE_TYPE_SHOUD_NOT_USE; |
| 121 | } |
| 122 | } |
| 123 | """ |
keunyoung | 15882e5 | 2015-09-16 16:57:58 -0700 | [diff] [blame] | 124 | #now implement getVehiclePropertyName |
| 125 | print \ |
| 126 | """public static String getVehiclePropertyName(int property) { |
| 127 | switch (property) {""" |
| 128 | for p in props: |
keunyoung | d32f4e6 | 2015-09-21 11:33:06 -0700 | [diff] [blame] | 129 | if (p.startEnd == 0): |
| 130 | print "case " + p.name + ': return "' + p.name + '";' |
keunyoung | 15882e5 | 2015-09-16 16:57:58 -0700 | [diff] [blame] | 131 | print \ |
| 132 | """default: return "UNKNOWN_PROPERTY"; |
| 133 | } |
| 134 | } |
| 135 | """ |
keunyoung | 1ab8e18 | 2015-09-24 09:25:22 -0700 | [diff] [blame] | 136 | #now implement getVehicleChangeMode |
| 137 | print \ |
| 138 | """public static int[] getVehicleChangeMode(int property) { |
| 139 | switch (property) {""" |
| 140 | for p in props: |
| 141 | if p.changeMode != "": |
| 142 | modes = p.changeMode.split('|') |
| 143 | modesString = [] |
| 144 | for m in modes: |
| 145 | modesString.append("VehiclePropChangeMode." + m) |
| 146 | print "case " + p.name + ": return new int[] { " + " , ".join(modesString) + " };" |
| 147 | print \ |
| 148 | """default: return null; |
| 149 | } |
| 150 | } |
| 151 | """ |
| 152 | #now implement getVehicleAccess |
| 153 | print \ |
keunyoung | a74b9ca | 2015-10-21 13:33:58 -0700 | [diff] [blame] | 154 | """public static int[] getVehicleAccess(int property) { |
keunyoung | 1ab8e18 | 2015-09-24 09:25:22 -0700 | [diff] [blame] | 155 | switch (property) {""" |
| 156 | for p in props: |
| 157 | if p.access != "": |
keunyoung | a74b9ca | 2015-10-21 13:33:58 -0700 | [diff] [blame] | 158 | accesses = p.access.split('|') |
| 159 | accessesString = [] |
| 160 | for a in accesses: |
| 161 | accessesString.append("VehiclePropAccess." + a) |
| 162 | print "case " + p.name + ": return new int[] { " + " , ".join(accessesString) + " };" |
keunyoung | 1ab8e18 | 2015-09-24 09:25:22 -0700 | [diff] [blame] | 163 | print \ |
keunyoung | a74b9ca | 2015-10-21 13:33:58 -0700 | [diff] [blame] | 164 | """default: return null; |
keunyoung | 1ab8e18 | 2015-09-24 09:25:22 -0700 | [diff] [blame] | 165 | } |
| 166 | } |
| 167 | """ |
Vitalii Tomkiv | 5f537ee | 2016-10-11 14:26:44 -0700 | [diff] [blame] | 168 | #now implement getVehicleZoneType |
| 169 | print \ |
| 170 | """public static int getVehicleZoneType(int property) { |
| 171 | switch (property) {""" |
| 172 | for p in props: |
| 173 | if p.zoneType != "": |
| 174 | print "case " + p.name + ": return VehicleZoneType." + p.zoneType + " ;" |
| 175 | print \ |
| 176 | """default: return VehicleZoneType.VEHICLE_ZONE_TYPE_NONE; |
| 177 | } |
| 178 | } |
| 179 | """ |
keunyoung | 15882e5 | 2015-09-16 16:57:58 -0700 | [diff] [blame] | 180 | |
| 181 | def printEnum(e): |
| 182 | print "public static class " + toJavaStyleName(e.name) + " {" |
| 183 | for entry in e.enums: |
| 184 | print JAVA_INT_DEF + entry[0] + " = " + entry[1] + ";" |
keunyoung | d32f4e6 | 2015-09-21 11:33:06 -0700 | [diff] [blame] | 185 | #now implement enumToString |
| 186 | print \ |
| 187 | """public static String enumToString(int v) { |
| 188 | switch(v) {""" |
| 189 | valueStore = [] |
| 190 | for entry in e.enums: |
| 191 | # handling enum with the same value. Print only 1st one. |
| 192 | if valueStore.count(entry[1]) == 0: |
| 193 | valueStore.append(entry[1]) |
| 194 | print "case " + entry[0] + ': return "' + entry[0] + '";' |
| 195 | print \ |
| 196 | """default: return "UNKNOWN"; |
| 197 | } |
| 198 | } |
| 199 | } |
| 200 | """ |
keunyoung | 15882e5 | 2015-09-16 16:57:58 -0700 | [diff] [blame] | 201 | |
| 202 | def printEnums(enums): |
| 203 | for e in enums: |
| 204 | printEnum(e) |
| 205 | |
Keun-young Park | 4c6834a | 2016-06-28 12:58:23 -0700 | [diff] [blame] | 206 | def printExtAudioRoutingSources(audio_ext_routing): |
| 207 | for r in audio_ext_routing: |
| 208 | print "public static final String VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_SOURCE_" + r + ' = "' + r + '";' |
| 209 | |
keunyoung | 15882e5 | 2015-09-16 16:57:58 -0700 | [diff] [blame] | 210 | def main(argv): |
| 211 | vehicle_h_path = os.path.dirname(os.path.abspath(__file__)) + "/../../../../../hardware/libhardware/include/hardware/vehicle.h" |
| 212 | #print vehicle_h_path |
| 213 | f = open(vehicle_h_path, 'r') |
| 214 | text = f.read() |
| 215 | f.close() |
keunyoung | d32f4e6 | 2015-09-21 11:33:06 -0700 | [diff] [blame] | 216 | vehicle_internal_h_path = os.path.dirname(os.path.abspath(__file__)) + "/../include/vehicle-internal.h" |
| 217 | f = open(vehicle_internal_h_path, 'r') |
| 218 | text = text + f.read() |
| 219 | f.close() |
keunyoung | 15882e5 | 2015-09-16 16:57:58 -0700 | [diff] [blame] | 220 | |
| 221 | props = [] |
| 222 | property_re = re.compile(RE_PROPERTY_PATTERN, re.MULTILINE | re.DOTALL) |
| 223 | for match in property_re.finditer(text): |
| 224 | words = match.group(1).split() |
Vitalii Tomkiv | 5f537ee | 2016-10-11 14:26:44 -0700 | [diff] [blame] | 225 | name = "VEHICLE_PROPERTY_" + match.group(3) |
| 226 | value = match.group(4) |
keunyoung | 15882e5 | 2015-09-16 16:57:58 -0700 | [diff] [blame] | 227 | if (value[0] == "(" and value[-1] == ")"): |
| 228 | value = value[1:-1] |
| 229 | prop = PropertyInfo(value, name) |
| 230 | i = 0 |
| 231 | while i < len(words): |
| 232 | if words[i] == "@value_type": |
| 233 | i += 1 |
| 234 | prop.type = words[i] |
| 235 | elif words[i] == "@change_mode": |
| 236 | i += 1 |
| 237 | prop.changeMode = words[i] |
| 238 | elif words[i] == "@access": |
| 239 | i += 1 |
| 240 | prop.access = words[i] |
| 241 | elif words[i] == "@unit": |
| 242 | i += 1 |
keunyoung | 1ab8e18 | 2015-09-24 09:25:22 -0700 | [diff] [blame] | 243 | prop.unit = words[i] |
Vitalii Tomkiv | 5f537ee | 2016-10-11 14:26:44 -0700 | [diff] [blame] | 244 | elif words[i] == "@zone_type": |
| 245 | i += 1 |
| 246 | prop.zoneType = words[i] |
keunyoung | d32f4e6 | 2015-09-21 11:33:06 -0700 | [diff] [blame] | 247 | elif words[i] == "@range_start" or words[i] == "@range_end": |
| 248 | prop.startEnd = 1 |
keunyoung | 15882e5 | 2015-09-16 16:57:58 -0700 | [diff] [blame] | 249 | i += 1 |
| 250 | props.append(prop) |
| 251 | #for p in props: |
| 252 | # print p |
| 253 | |
| 254 | enums = [] |
| 255 | enum_re = re.compile(RE_ENUM_PATTERN, re.MULTILINE | re.DOTALL) |
| 256 | enum_entry_re = re.compile(RE_ENUM_ENTRY_PATTERN, re.MULTILINE) |
| 257 | for match in enum_re.finditer(text): |
| 258 | name = match.group(1) |
| 259 | info = EnumInfo(name) |
| 260 | for match_entry in enum_entry_re.finditer(match.group(2)): |
| 261 | valueName = match_entry.group(1) |
| 262 | value = match_entry.group(2) |
| 263 | #print valueName, value |
| 264 | if value[-1] == ',': |
| 265 | value = value[:-1] |
| 266 | info.addEntry(valueName, value) |
| 267 | enums.append(info) |
| 268 | #for e in enums: |
| 269 | # print e |
Keun-young Park | 4c6834a | 2016-06-28 12:58:23 -0700 | [diff] [blame] | 270 | |
| 271 | audio_ext_routing = [] |
| 272 | audio_ext_routing_re = re.compile(RE_AUDIO_EXT_ROUTING_PATTERN, re.MULTILINE | re.DOTALL) |
| 273 | for match in audio_ext_routing_re.finditer(text): |
| 274 | #print match |
| 275 | name = match.group(1) |
| 276 | value = match.group(2) |
| 277 | if name != value: |
| 278 | print "Warning, AUDIO_EXT_ROUTING_SOURCE_" + name + " does not match " + value |
| 279 | else: |
| 280 | audio_ext_routing.append(name) |
| 281 | |
keunyoung | 15882e5 | 2015-09-16 16:57:58 -0700 | [diff] [blame] | 282 | print JAVA_HEADER |
| 283 | printProperties(props) |
Keun-young Park | 4c6834a | 2016-06-28 12:58:23 -0700 | [diff] [blame] | 284 | print "\n\n" |
| 285 | printExtAudioRoutingSources(audio_ext_routing) |
| 286 | print "\n\n" |
keunyoung | 15882e5 | 2015-09-16 16:57:58 -0700 | [diff] [blame] | 287 | printEnums(enums) |
| 288 | print JAVA_TRAIL |
Keun-young Park | 4c6834a | 2016-06-28 12:58:23 -0700 | [diff] [blame] | 289 | |
keunyoung | 15882e5 | 2015-09-16 16:57:58 -0700 | [diff] [blame] | 290 | if __name__ == '__main__': |
| 291 | main(sys.argv) |