Home | History | Annotate | Download | only in tool
      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 
     40 //Autogenerated from vehicle.h using libvehiclenetwork/tool/vehicle_code_gen.py.
     41 //Do not modify manually.
     42 
     43 package com.android.car.vehiclenetwork;
     44 
     45 public class VehicleNetworkConsts {
     46 """
     47 
     48 JAVA_TRAIL = \
     49 """
     50 }
     51 """
     52 
     53 RE_PROPERTY_PATTERN = r'/\*\*(.*?)\*/\n\#define\s+VEHICLE_PROPERTY_(\S+)\s+(\S+)'
     54 RE_ENUM_PATTERN = r'enum\s+(\S+)\s+\{\S*(.*?)\}'
     55 RE_ENUM_ENTRY_PATTERN = r'(\S+)\s*=\s*(.*?)[,\n]'
     56 
     57 class PropertyInfo(object):
     58   def __init__(self, value, name):
     59     self.value = value
     60     self.name = name
     61     self.type = ""
     62     self.changeMode = ""
     63     self.access = ""
     64     self.unit = ""
     65     self.startEnd = 0 # _START/END property
     66 
     67   def __str__(self):
     68     r = ["value:" + self.value]
     69     r.append("name:" + self.name)
     70     if self.type != "":
     71       r.append("type:" + self.type)
     72     if self.changeMode != "":
     73       r.append("changeMode:" + self.changeMode)
     74     if self.access != "":
     75       r.append("access:" + self.access)
     76     if self.unit != "":
     77       r.append("unit:" + self.unit)
     78     return " ".join(r)
     79 
     80 class EnumInfo(object):
     81   def __init__(self, name):
     82     self.name = name
     83     self.enums = [] #(name, value) tuple
     84   def addEntry(self, name, value):
     85     self.enums.append((name, value))
     86   def __str__(self):
     87     r = [self.name + "\n"]
     88     for e in self.enums:
     89       r.append("  " + e[0] + ":" + e[1] + "\n")
     90     return ''.join(r)
     91 
     92 def toJavaStyleName(name):
     93   # do not convert if 1st letter is already upper
     94   if name[0].isupper():
     95     return name
     96   words = name.split("_")
     97   #print words
     98   for i in range(len(words)):
     99     w = words[i]
    100     w = w[0].upper() + w[1:]
    101     words[i] = w
    102   return ''.join(words)
    103 
    104 JAVA_INT_DEF = "public static final int "
    105 def printProperties(props):
    106   for p in props:
    107     print JAVA_INT_DEF + p.name + " = " + p.value + ";"
    108 
    109   #now impement getVehicleValueType
    110   print \
    111 """public static int getVehicleValueType(int property) {
    112 switch (property) {"""
    113   for p in props:
    114     if p.type != "":
    115       print "case " + p.name + ": return VehicleValueType." + p.type + ";"
    116   print \
    117 """default: return VehicleValueType.VEHICLE_VALUE_TYPE_SHOUD_NOT_USE;
    118 }
    119 }
    120 """
    121   #now implement getVehiclePropertyName
    122   print \
    123 """public static String getVehiclePropertyName(int property) {
    124 switch (property) {"""
    125   for p in props:
    126     if (p.startEnd == 0):
    127       print "case " + p.name + ': return "' + p.name +     '";'
    128   print \
    129 """default: return "UNKNOWN_PROPERTY";
    130 }
    131 }
    132 """
    133   #now implement getVehicleChangeMode
    134   print \
    135 """public static int[] getVehicleChangeMode(int property) {
    136 switch (property) {"""
    137   for p in props:
    138     if p.changeMode != "":
    139       modes = p.changeMode.split('|')
    140       modesString = []
    141       for m in modes:
    142         modesString.append("VehiclePropChangeMode." + m)
    143       print "case " + p.name + ": return new int[] { " + " , ".join(modesString) + " };"
    144   print \
    145 """default: return null;
    146 }
    147 }
    148 """
    149   #now implement getVehicleAccess
    150   print \
    151 """public static int[] getVehicleAccess(int property) {
    152 switch (property) {"""
    153   for p in props:
    154     if p.access != "":
    155       accesses = p.access.split('|')
    156       accessesString = []
    157       for a in accesses:
    158         accessesString.append("VehiclePropAccess." + a)
    159       print "case " + p.name + ": return new int[] { " + " , ".join(accessesString) + " };"
    160   print \
    161 """default: return null;
    162 }
    163 }
    164 """
    165 
    166 def printEnum(e):
    167   print "public static class " + toJavaStyleName(e.name) + " {"
    168   for entry in e.enums:
    169     print JAVA_INT_DEF + entry[0] + " = " + entry[1] + ";"
    170   #now implement enumToString
    171   print \
    172 """public static String enumToString(int v) {
    173 switch(v) {"""
    174   valueStore = []
    175   for entry in e.enums:
    176     # handling enum with the same value. Print only 1st one.
    177     if valueStore.count(entry[1]) == 0:
    178       valueStore.append(entry[1])
    179       print "case " + entry[0] + ': return "' + entry[0] + '";'
    180   print \
    181 """default: return "UNKNOWN";
    182 }
    183 }
    184 }
    185 """
    186 
    187 def printEnums(enums):
    188   for e in enums:
    189     printEnum(e)
    190 
    191 def main(argv):
    192   vehicle_h_path = os.path.dirname(os.path.abspath(__file__)) + "/../../../../../hardware/libhardware/include/hardware/vehicle.h"
    193   #print vehicle_h_path
    194   f = open(vehicle_h_path, 'r')
    195   text = f.read()
    196   f.close()
    197   vehicle_internal_h_path = os.path.dirname(os.path.abspath(__file__)) + "/../include/vehicle-internal.h"
    198   f = open(vehicle_internal_h_path, 'r')
    199   text = text + f.read()
    200   f.close()
    201 
    202   props = []
    203   property_re = re.compile(RE_PROPERTY_PATTERN, re.MULTILINE | re.DOTALL)
    204   for match in property_re.finditer(text):
    205     words = match.group(1).split()
    206     name = "VEHICLE_PROPERTY_" + match.group(2)
    207     value = match.group(3)
    208     if (value[0] == "(" and value[-1] == ")"):
    209       value = value[1:-1]
    210     prop = PropertyInfo(value, name)
    211     i = 0
    212     while i < len(words):
    213       if words[i] == "@value_type":
    214         i += 1
    215         prop.type = words[i]
    216       elif words[i] == "@change_mode":
    217         i += 1
    218         prop.changeMode = words[i]
    219       elif words[i] == "@access":
    220         i += 1
    221         prop.access = words[i]
    222       elif words[i] == "@unit":
    223         i += 1
    224         prop.unit = words[i]
    225       elif words[i] == "@range_start" or words[i] == "@range_end":
    226         prop.startEnd = 1
    227       i += 1
    228     props.append(prop)
    229     #for p in props:
    230     #  print p
    231 
    232   enums = []
    233   enum_re = re.compile(RE_ENUM_PATTERN, re.MULTILINE | re.DOTALL)
    234   enum_entry_re = re.compile(RE_ENUM_ENTRY_PATTERN, re.MULTILINE)
    235   for match in enum_re.finditer(text):
    236     name = match.group(1)
    237     info = EnumInfo(name)
    238     for match_entry in enum_entry_re.finditer(match.group(2)):
    239       valueName = match_entry.group(1)
    240       value = match_entry.group(2)
    241       #print valueName, value
    242       if value[-1] == ',':
    243         value = value[:-1]
    244       info.addEntry(valueName, value)
    245     enums.append(info)
    246   #for e in enums:
    247   #  print e
    248   print JAVA_HEADER
    249   printProperties(props)
    250   printEnums(enums)
    251   print JAVA_TRAIL
    252 if __name__ == '__main__':
    253   main(sys.argv)
    254 
    255