1#!/usr/bin/env python
2#
3# This software is licensed under the terms of the GNU General Public
4# License version 2, as published by the Free Software Foundation, and
5# may be copied, distributed, and modified under those terms.
6#
7# This program is distributed in the hope that it will be useful,
8# but WITHOUT ANY WARRANTY; without even the implied warranty of
9# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10# GNU General Public License for more details.
11#
12# this script is used to generate 'android/avd/hw-config.h' by
13# parsing 'android/avd/hardware-properties.ini'
14#
15#
16import  sys, os, string, re
17
18# location of source file, relative to current program directory
19relativeSourcePath = "../avd/hardware-properties.ini"
20
21# location of target file, relative to current program directory
22relativeTargetPath = "../avd/hw-config-defs.h"
23
24def quoteStringForC(str):
25    """quote a string so it can be used in C"""
26    return '\\"'.join('"'+p+'"' for p in str.split('"'))
27
28# a dictionary that maps item types as they appear in the .ini
29# file into macro names in the generated C header
30#
31typesToMacros = {
32    'integer': 'HWCFG_INT',
33    'string': 'HWCFG_STRING',
34    'boolean': 'HWCFG_BOOL',
35    'diskSize': 'HWCFG_DISKSIZE',
36    'double': 'HWCFG_DOUBLE'
37    }
38
39# the list of macro names
40macroNames = typesToMacros.values()
41
42# target program header
43targetHeader = """\
44/* this file is automatically generated from 'hardware-properties.ini'
45 * DO NOT EDIT IT. To re-generate it, use android/tools/gen-hw-config.py'
46 */
47"""
48
49# locate source and target
50programDir = os.path.dirname(sys.argv[0])
51if len(sys.argv) != 3:
52    print "Usage: %s source target\n" % os.path.basename(sys.argv[0])
53    sys.exit(1)
54
55sourceFile = sys.argv[1]
56targetFile = sys.argv[2]
57
58# parse the source file and record items
59# I would love to use Python's ConfigParser, but it doesn't
60# support files without sections, or multiply defined items
61#
62items    = []
63lastItem = None
64
65class Item:
66    def __init__(self,name):
67        self.name     = name
68        self.type     = type
69        self.default  = None
70        self.abstract = ""
71        self.description = ""
72        self.enum_values = []
73
74    def add(self,key,val):
75        if key == 'type':
76            self.type = val
77        elif key == 'enum':
78            # Build list of enumerated values
79            self.enum_values = [ s.strip() for s in val.split(',') ]
80            # If default value has been already set, make sure it's in the list
81            if self.default and not self.default in self.enum_values:
82                print "Property '" + self.name + "': Default value '" + self.default + "' is missing in enum: ",
83                print self.enum_values,
84                sys.exit(1)
85        elif key == 'default':
86            # If this is an enum, make sure that default value is in the list.
87            if val and self.enum_values and not val in self.enum_values:
88                print "Property '" + self.name + "': Default value '" + val + "' is missing in enum: ",
89                print self.enum_values,
90                sys.exit(1)
91            else:
92                self.default = val
93        elif key == 'abstract':
94            self.abstract = val
95        elif key == 'description':
96            self.description = val
97
98for line in open(sourceFile):
99    line = line.strip()
100    # ignore empty lines and comments
101    if len(line) == 0 or line[0] in ";#":
102        continue
103    key, value = line.split('=')
104
105    key   = key.strip()
106    value = value.strip()
107
108    if key == 'name':
109        if lastItem: items.append(lastItem)
110        lastItem = Item(value)
111    else:
112        lastItem.add(key, value)
113
114if lastItem:
115    items.append(lastItem)
116
117if targetFile == '--':
118    out = sys.stdout
119else:
120    out = open(targetFile,"wb")
121
122out.write(targetHeader)
123
124# write guards to prevent bad compiles
125for m in macroNames:
126    out.write("""\
127#ifndef %(macro)s
128#error  %(macro)s not defined
129#endif
130""" % { 'macro':m })
131out.write("\n")
132
133for item in items:
134    if item.type == None:
135        sys.stderr.write("ignoring config item with no type '%s'\n" % item.name)
136        continue
137
138    if not typesToMacros.has_key(item.type):
139        sys.stderr.write("ignoring config item with unknown type '%s': '%s'\n" % \
140                (item.type, item.name))
141        continue
142
143    if item.default == None:
144        sys.stderr.write("ignoring config item with no default '%s' */" % item.name)
145        continue
146
147    # convert dots into underscores
148    varMacro   = typesToMacros[item.type]
149    varNameStr = quoteStringForC(item.name)
150    varName    = item.name.replace(".","_")
151    varDefault = item.default
152    varAbstract = quoteStringForC(item.abstract)
153    varDesc     = quoteStringForC(item.description)
154
155    if item.type in [ 'string', 'boolean', 'diskSize' ]:
156        # quote default value for strings
157        varDefault = quoteStringForC(varDefault)
158
159    out.write("%s(\n  %s,\n  %s,\n  %s,\n  %s,\n  %s)\n\n" % \
160            (varMacro,varName,varNameStr,varDefault,varAbstract,varDesc))
161
162
163for m in macroNames:
164    out.write("#undef %s\n" % m)
165
166out.write("/* end of auto-generated file */\n")
167out.close()
168