1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
|
#!/usr/bin/env python
#
# This software is licensed under the terms of the GNU General Public
# License version 2, as published by the Free Software Foundation, and
# may be copied, distributed, and modified under those terms.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# this script is used to generate 'android/avd/hw-config.h' by
# parsing 'android/avd/hardware-properties.ini'
#
#
import sys, os, string, re
# location of source file, relative to current program directory
relativeSourcePath = "../avd/hardware-properties.ini"
# location of target file, relative to current program directory
relativeTargetPath = "../avd/hw-config-defs.h"
def quoteStringForC(str):
"""quote a string so it can be used in C"""
return '\\"'.join('"'+p+'"' for p in str.split('"'))
# a dictionary that maps item types as they appear in the .ini
# file into macro names in the generated C header
#
typesToMacros = {
'integer': 'HWCFG_INT',
'string': 'HWCFG_STRING',
'boolean': 'HWCFG_BOOL',
'diskSize': 'HWCFG_DISKSIZE',
'double': 'HWCFG_DOUBLE'
}
# the list of macro names
macroNames = typesToMacros.values()
# target program header
targetHeader = """\
/* this file is automatically generated from 'hardware-properties.ini'
* DO NOT EDIT IT. To re-generate it, use android/tools/gen-hw-config.py'
*/
"""
# locate source and target
programDir = os.path.dirname(sys.argv[0])
if len(sys.argv) != 3:
print "Usage: %s source target\n" % os.path.basename(sys.argv[0])
sys.exit(1)
sourceFile = sys.argv[1]
targetFile = sys.argv[2]
# parse the source file and record items
# I would love to use Python's ConfigParser, but it doesn't
# support files without sections, or multiply defined items
#
items = []
lastItem = None
class Item:
def __init__(self,name):
self.name = name
self.type = type
self.default = None
self.abstract = ""
self.description = ""
self.enum_values = []
# gets base type for an enum value.
# This is a very basic implementation of enum parser that assumes that enum
# is formatted as such:
#
# enum(type: val1[, val2[, ..., valN] [, ...])
#
# where:
# - 'type' defines type of enumerated values, and must be one of the types
# listed in typesToMacros
# - 'val1'... 'valN' lists enumerated values, separated with a comma.
# - '...' is a special value indicating that AVD editor may set property
# value that doesn't match values enumerated in the .ini file. However,
# default value set for the property must match one of the enumerated
# values.
# This method provides some basic checking for the format, but it could, or
# should be improved.
#
def trueenumtype(self,type):
# Make sure enum ends with a ')'
if not type.endswith(")"):
print"Bad enum fomat in '" + type + "'"
sys.exit(1)
# Cut substring between 'enum(', and terminating ')'
enum_data = type[5:len(type)-1]
# Locate enum's value type
type_index = enum_data.find(':')
if type_index == -1:
print "Property '" + self.name + "': Value type is missing in enum."
sys.exit(1)
value_type = enum_data[:type_index].strip()
# Make sure value type is known
if not value_type in typesToMacros:
print "Property '" + self.name + "': Unknown value type '" + value_type + "' in enum."
sys.exit(1)
# Save list of enumerated values, stripped of spaces.
for value in enum_data[type_index+1:].split(','):
self.enum_values.append(value.strip())
return value_type
# gets true basic type for a type obtained from the .ini file
# Here we simply check if type is an enum, and if so, we extract basic
# type for enumerated values.
def truetype(self,type):
if type.startswith("enum("):
return self.trueenumtype(type.strip())
return type
def add(self,key,val):
if key == 'type':
self.type = self.truetype(val)
elif key == 'default':
if len(val) > 0 and len(self.enum_values) > 0:
# Make sure that default value (if set) is present in enum.
if self.enum_values.count(val) == 0:
print "Property '" + self.name + "': Default value '" + val + "' is missing in enum: ",
print self.enum_values,
sys.exit(1)
else:
self.default = val
else:
self.default = val
elif key == 'abstract':
self.abstract = val
elif key == 'description':
self.description = val
for line in open(sourceFile):
line = line.strip()
# ignore empty lines and comments
if len(line) == 0 or line[0] in ";#":
continue
key, value = line.split('=')
key = key.strip()
value = value.strip()
if key == 'name':
if lastItem: items.append(lastItem)
lastItem = Item(value)
else:
lastItem.add(key, value)
if lastItem:
items.append(lastItem)
if targetFile == '--':
out = sys.stdout
else:
out = open(targetFile,"wb")
out.write(targetHeader)
# write guards to prevent bad compiles
for m in macroNames:
out.write("""\
#ifndef %(macro)s
#error %(macro)s not defined
#endif
""" % { 'macro':m })
out.write("\n")
for item in items:
if item.type == None:
sys.stderr.write("ignoring config item with no type '%s'\n" % item.name)
continue
if not typesToMacros.has_key(item.type):
sys.stderr.write("ignoring config item with unknown type '%s': '%s'\n" % \
(item.type, item.name))
continue
if item.default == None:
sys.stderr.write("ignoring config item with no default '%s' */" % item.name)
continue
# convert dots into underscores
varMacro = typesToMacros[item.type]
varNameStr = quoteStringForC(item.name)
varName = item.name.replace(".","_")
varDefault = item.default
varAbstract = quoteStringForC(item.abstract)
varDesc = quoteStringForC(item.description)
if item.type in [ 'string', 'boolean', 'diskSize' ]:
# quote default value for strings
varDefault = quoteStringForC(varDefault)
out.write("%s(\n %s,\n %s,\n %s,\n %s,\n %s)\n\n" % \
(varMacro,varName,varNameStr,varDefault,varAbstract,varDesc))
for m in macroNames:
out.write("#undef %s\n" % m)
out.write("/* end of auto-generated file */\n")
out.close()
|