OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # | 2 # |
3 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 3 # Copyright (c) 2011 The Chromium Authors. All rights reserved. |
4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
6 | 6 |
7 """ Generator for C style prototypes and definitions """ | 7 """ Generator for C style prototypes and definitions """ |
8 | 8 |
9 import glob | 9 import glob |
10 import os | 10 import os |
11 import sys | 11 import sys |
12 import subprocess | |
13 | 12 |
14 from idl_log import ErrOut, InfoOut, WarnOut | 13 from idl_log import ErrOut, InfoOut, WarnOut |
15 from idl_node import IDLAttribute, IDLNode | 14 from idl_node import IDLAttribute, IDLNode |
16 from idl_ast import IDLAst | 15 from idl_ast import IDLAst |
17 from idl_option import GetOption, Option, ParseOptions | 16 from idl_option import GetOption, Option, ParseOptions |
18 from idl_outfile import IDLOutFile | 17 from idl_outfile import IDLOutFile |
19 from idl_parser import ParseFiles | 18 from idl_parser import ParseFiles |
20 from idl_c_proto import CGen, GetNodeComments, CommentLines, Comment | 19 from idl_c_proto import CGen, GetNodeComments, CommentLines, Comment |
21 from idl_generator import Generator, GeneratorByFile | 20 from idl_generator import Generator, GeneratorByFile |
22 | 21 |
23 Option('dstroot', 'Base directory of output', default=os.path.join('..', 'c')) | 22 Option('dstroot', 'Base directory of output', default=os.path.join('..', 'c')) |
24 Option('guard', 'Include guard prefix', default=os.path.join('ppapi', 'c')) | 23 Option('guard', 'Include guard prefix', default=os.path.join('ppapi', 'c')) |
25 Option('out', 'List of output files', default='') | 24 Option('out', 'List of output files', default='') |
26 | 25 |
| 26 |
27 def GetOutFileName(filenode, relpath=None, prefix=None): | 27 def GetOutFileName(filenode, relpath=None, prefix=None): |
28 path, name = os.path.split(filenode.GetProperty('NAME')) | 28 path, name = os.path.split(filenode.GetProperty('NAME')) |
29 name = os.path.splitext(name)[0] + '.h' | 29 name = os.path.splitext(name)[0] + '.h' |
30 if prefix: name = '%s%s' % (prefix, name) | 30 if prefix: name = '%s%s' % (prefix, name) |
31 if path: name = os.path.join(path, name) | 31 if path: name = os.path.join(path, name) |
32 if relpath: name = os.path.join(relpath, name) | 32 if relpath: name = os.path.join(relpath, name) |
33 return name | 33 return name |
34 | 34 |
| 35 |
35 def WriteGroupMarker(out, node, last_group): | 36 def WriteGroupMarker(out, node, last_group): |
36 # If we are part of a group comment marker... | 37 # If we are part of a group comment marker... |
37 if last_group and last_group != node.cls: | 38 if last_group and last_group != node.cls: |
38 pre = CommentLines(['*',' @}', '']) + '\n' | 39 pre = CommentLines(['*',' @}', '']) + '\n' |
39 else: | 40 else: |
40 pre = '\n' | 41 pre = '\n' |
41 | 42 |
42 if node.cls in ['Typedef', 'Interface', 'Struct', 'Enum']: | 43 if node.cls in ['Typedef', 'Interface', 'Struct', 'Enum']: |
43 if last_group != node.cls: | 44 if last_group != node.cls: |
44 pre += CommentLines(['*',' @addtogroup %ss' % node.cls, ' @{', '']) | 45 pre += CommentLines(['*',' @addtogroup %ss' % node.cls, ' @{', '']) |
45 last_group = node.cls | 46 last_group = node.cls |
46 else: | 47 else: |
47 last_group = None | 48 last_group = None |
48 out.Write(pre) | 49 out.Write(pre) |
49 return last_group | 50 return last_group |
50 | 51 |
51 | 52 |
52 def GenerateHeader(out, filenode, releases): | 53 def GenerateHeader(out, filenode, releases): |
53 gpath = GetOption('guard') | |
54 cgen = CGen() | 54 cgen = CGen() |
55 pref = '' | 55 pref = '' |
56 do_comments = True | 56 do_comments = True |
57 | 57 |
58 # Generate definitions. | 58 # Generate definitions. |
59 last_group = None | 59 last_group = None |
60 top_types = ['Typedef', 'Interface', 'Struct', 'Enum', 'Inline'] | 60 top_types = ['Typedef', 'Interface', 'Struct', 'Enum', 'Inline'] |
61 for node in filenode.GetListOf(*top_types): | 61 for node in filenode.GetListOf(*top_types): |
62 # Skip if this node is not in this release | 62 # Skip if this node is not in this release |
63 if not node.InReleases(releases): | 63 if not node.InReleases(releases): |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 | 96 |
97 if item: out.Write(item) | 97 if item: out.Write(item) |
98 if last_group: | 98 if last_group: |
99 out.Write(CommentLines(['*',' @}', '']) + '\n') | 99 out.Write(CommentLines(['*',' @}', '']) + '\n') |
100 | 100 |
101 | 101 |
102 class HGen(GeneratorByFile): | 102 class HGen(GeneratorByFile): |
103 def __init__(self): | 103 def __init__(self): |
104 Generator.__init__(self, 'C Header', 'cgen', 'Generate the C headers.') | 104 Generator.__init__(self, 'C Header', 'cgen', 'Generate the C headers.') |
105 | 105 |
106 def GetMacro(self, node): | 106 def GenerateFile(self, filenode, releases, options): |
107 name = node.GetName() | |
108 name = name.upper() | |
109 return "%s_INTERFACE" % name | |
110 | |
111 def GetDefine(self, name, value): | |
112 out = '#define %s %s' % (name, value) | |
113 if len(out) > 80: | |
114 out = '#define %s \\\n %s' % (name, value) | |
115 return '%s\n' % out | |
116 | |
117 def GetVersionString(self, node): | |
118 # If an interface name is specified, use that | |
119 iname = node.GetProperty('iname') | |
120 if iname: return iname | |
121 | |
122 # Otherwise, the interface name is the object's name | |
123 # With '_Dev' replaced by '(Dev)' if it's a Dev interface. | |
124 name = node.GetName() | |
125 if len(name) > 4 and name[-4:] == '_Dev': | |
126 name = '%s(Dev)' % name[:-4] | |
127 return name | |
128 | |
129 def GetOutFile(self, filenode, options): | |
130 savename = GetOutFileName(filenode, GetOption('dstroot')) | 107 savename = GetOutFileName(filenode, GetOption('dstroot')) |
131 return IDLOutFile(savename) | 108 out = IDLOutFile(savename) |
| 109 self.GenerateHead(out, filenode, releases, options) |
| 110 self.GenerateBody(out, filenode, releases, options) |
| 111 self.GenerateTail(out, filenode, releases, options) |
| 112 return out.Close() |
132 | 113 |
133 def GenerateHead(self, out, filenode, releases, options): | 114 def GenerateHead(self, out, filenode, releases, options): |
| 115 __pychecker__ = 'unusednames=options' |
134 cgen = CGen() | 116 cgen = CGen() |
135 gpath = GetOption('guard') | 117 gpath = GetOption('guard') |
136 release = releases[0] | 118 release = releases[0] |
137 def_guard = GetOutFileName(filenode, relpath=gpath) | 119 def_guard = GetOutFileName(filenode, relpath=gpath) |
138 def_guard = def_guard.replace(os.sep,'_').replace('.','_').upper() + '_' | 120 def_guard = def_guard.replace(os.sep,'_').replace('.','_').upper() + '_' |
139 | 121 |
140 cright_node = filenode.GetChildren()[0] | 122 cright_node = filenode.GetChildren()[0] |
141 assert(cright_node.IsA('Copyright')) | 123 assert(cright_node.IsA('Copyright')) |
142 fileinfo = filenode.GetChildren()[1] | 124 fileinfo = filenode.GetChildren()[1] |
143 assert(fileinfo.IsA('Comment')) | 125 assert(fileinfo.IsA('Comment')) |
(...skipping 25 matching lines...) Expand all Loading... |
169 includes = sorted(set(includes)) | 151 includes = sorted(set(includes)) |
170 cur_include = GetOutFileName(filenode, relpath=gpath).replace(os.sep, '/') | 152 cur_include = GetOutFileName(filenode, relpath=gpath).replace(os.sep, '/') |
171 for include in includes: | 153 for include in includes: |
172 if include == cur_include: continue | 154 if include == cur_include: continue |
173 out.Write('#include "%s"\n' % include) | 155 out.Write('#include "%s"\n' % include) |
174 | 156 |
175 # Generate all interface defines | 157 # Generate all interface defines |
176 out.Write('\n') | 158 out.Write('\n') |
177 for node in filenode.GetListOf('Interface'): | 159 for node in filenode.GetListOf('Interface'): |
178 idefs = '' | 160 idefs = '' |
179 name = self.GetVersionString(node) | 161 macro = cgen.GetInterfaceMacro(node) |
180 macro = node.GetProperty('macro') | 162 for rel in node.GetUniqueReleases(releases): |
181 if not macro: | |
182 macro = self.GetMacro(node) | |
183 | |
184 unique = node.GetUniqueReleases(releases) | |
185 for rel in unique: | |
186 version = node.GetVersion(rel) | 163 version = node.GetVersion(rel) |
| 164 name = cgen.GetInterfaceString(node, version) |
187 strver = str(version).replace('.', '_') | 165 strver = str(version).replace('.', '_') |
188 idefs += self.GetDefine('%s_%s' % (macro, strver), | 166 idefs += cgen.GetDefine('%s_%s' % (macro, strver), '"%s"' % name) |
189 '"%s;%s"' % (name, version)) | 167 idefs += cgen.GetDefine(macro, '%s_%s' % (macro, strver)) + '\n' |
190 idefs += self.GetDefine(macro, '%s_%s' % (macro, strver)) + '\n' | |
191 out.Write(idefs) | 168 out.Write(idefs) |
192 | 169 |
193 # Generate the @file comment | 170 # Generate the @file comment |
194 out.Write('%s\n' % Comment(fileinfo, prefix='*\n @file')) | 171 out.Write('%s\n' % Comment(fileinfo, prefix='*\n @file')) |
195 | 172 |
196 def GenerateBody(self, out, filenode, releases, options): | 173 def GenerateBody(self, out, filenode, releases, options): |
| 174 __pychecker__ = 'unusednames=options' |
197 GenerateHeader(out, filenode, releases) | 175 GenerateHeader(out, filenode, releases) |
198 | 176 |
199 def GenerateTail(self, out, filenode, releases, options): | 177 def GenerateTail(self, out, filenode, releases, options): |
| 178 __pychecker__ = 'unusednames=options,releases' |
200 gpath = GetOption('guard') | 179 gpath = GetOption('guard') |
201 def_guard = GetOutFileName(filenode, relpath=gpath) | 180 def_guard = GetOutFileName(filenode, relpath=gpath) |
202 def_guard = def_guard.replace(os.sep,'_').replace('.','_').upper() + '_' | 181 def_guard = def_guard.replace(os.sep,'_').replace('.','_').upper() + '_' |
203 out.Write('#endif /* %s */\n\n' % def_guard) | 182 out.Write('#endif /* %s */\n\n' % def_guard) |
204 | 183 |
205 | 184 |
206 hgen = HGen() | 185 hgen = HGen() |
207 | 186 |
208 def Main(args): | 187 def Main(args): |
209 # Default invocation will verify the golden files are unchanged. | 188 # Default invocation will verify the golden files are unchanged. |
(...skipping 24 matching lines...) Expand all Loading... |
234 failed =1 | 213 failed =1 |
235 else: | 214 else: |
236 print "Golden file for M13-M15 passed." | 215 print "Golden file for M13-M15 passed." |
237 | 216 |
238 return failed | 217 return failed |
239 | 218 |
240 if __name__ == '__main__': | 219 if __name__ == '__main__': |
241 retval = Main(sys.argv[1:]) | 220 retval = Main(sys.argv[1:]) |
242 sys.exit(retval) | 221 sys.exit(retval) |
243 | 222 |
OLD | NEW |