Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(125)

Side by Side Diff: ppapi/generators/idl_c_header.py

Issue 7715036: More multi-version support (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ppapi/generators/idl_ast.py ('k') | ppapi/generators/idl_c_proto.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 12 import subprocess
13 13
14 from idl_log import ErrOut, InfoOut, WarnOut 14 from idl_log import ErrOut, InfoOut, WarnOut
15 from idl_node import IDLAttribute, IDLNode 15 from idl_node import IDLAttribute, IDLNode
16 from idl_ast import IDLAst 16 from idl_ast import IDLAst
17 from idl_option import GetOption, Option, ParseOptions 17 from idl_option import GetOption, Option, ParseOptions
18 from idl_outfile import IDLOutFile 18 from idl_outfile import IDLOutFile
19 from idl_parser import ParseFiles 19 from idl_parser import ParseFiles
20 from idl_c_proto import CGen 20 from idl_c_proto import CGen, GetNodeComments, CommentLines, Comment
21 from idl_generator import Generator 21 from idl_generator import Generator, GeneratorByFile
22 22
23 Option('dstroot', 'Base directory of output', default='../c') 23 Option('dstroot', 'Base directory of output', default='../c')
24 Option('guard', 'Include guard prefix', default='ppapi/c') 24 Option('guard', 'Include guard prefix', default='ppapi/c')
25 Option('out', 'List of output files', default='') 25 Option('out', 'List of output files', default='')
26 26
27 cgen = CGen() 27 def GetOutFileName(filenode, relpath=None, prefix=None):
28
29 def IDLToHeader(filenode, relpath=None, prefix=None):
30 path, name = os.path.split(filenode.GetProperty('NAME')) 28 path, name = os.path.split(filenode.GetProperty('NAME'))
31 name = os.path.splitext(name)[0] + '.h' 29 name = os.path.splitext(name)[0] + '.h'
32 if prefix: name = '%s%s' % (prefix, name) 30 if prefix: name = '%s%s' % (prefix, name)
33 if path: name = os.path.join(path, name) 31 if path: name = os.path.join(path, name)
34 if relpath: name = os.path.join(relpath, name) 32 if relpath: name = os.path.join(relpath, name)
35 return name 33 return name
36 34
35 def WriteGroupMarker(out, node, last_group):
36 # If we are part of a group comment marker...
37 if last_group and last_group != node.cls:
38 pre = CommentLines(['*',' @}', '']) + '\n'
39 else:
40 pre = '\n'
37 41
38 def GenerateHeader(filenode, release, pref, inline=True): 42 if node.cls in ['Typedef', 'Interface', 'Struct', 'Enum']:
39 name = filenode.GetProperty('NAME') 43 if last_group != node.cls:
40 # if name == 'pp_stdint.idl': return 44 pre += CommentLines(['*',' @addtogroup %ss' % node.cls, ' @{', ''])
45 last_group = node.cls
46 else:
47 last_group = None
48 out.Write(pre)
49 return last_group
41 50
42 # If we have an 'out' filter list, then check if we should output this file.
43 outlist = GetOption('out')
44 if outlist:
45 outlist = outlist.split(',')
46 if name not in outlist:
47 return
48 51
49 savename = IDLToHeader(filenode, relpath=GetOption('dstroot'), prefix=pref) 52 def GenerateHeader(out, filenode, releases):
50 out = IDLOutFile(savename)
51
52 gpath = GetOption('guard') 53 gpath = GetOption('guard')
53 def_guard = IDLToHeader(filenode, relpath=gpath, prefix=pref) 54 cgen = CGen()
54 def_guard = def_guard.replace('/','_').replace('.','_').upper() + '_' 55 pref = ''
55 cright_node = filenode.GetChildren()[0] 56 do_comments = True
56 assert(cright_node.IsA('Copyright'))
57
58 fileinfo = filenode.GetChildren()[1]
59 assert(fileinfo.IsA('Comment'))
60
61 out.Write('%s\n' % cgen.Copyright(cright_node))
62 out.Write('/* From %s modified %s. */\n\n'% (
63 filenode.GetProperty('NAME'), filenode.GetProperty('DATETIME')))
64 out.Write('#ifndef %s\n#define %s\n\n' % (def_guard, def_guard))
65
66 for label in filenode.GetListOf('Label'):
67 if label.GetName() == GetOption('label'):
68 cgen.SetVersionMap(label)
69
70 deps = filenode.GetDeps(release)
71 # Generate set of includes
72 includes = set([])
73 for dep in deps:
74 depfile = dep.GetProperty('FILE')
75 if depfile:
76 includes.add(depfile)
77 includes = [IDLToHeader(include, relpath=gpath) for include in includes]
78 includes.append('ppapi/c/pp_macros.h')
79
80 # Assume we need stdint if we "include" C or C++ code
81 if filenode.GetListOf('Include'):
82 includes.append('ppapi/c/pp_stdint.h')
83
84 includes = sorted(set(includes))
85 cur_include = IDLToHeader(filenode, relpath=gpath)
86 for include in includes:
87 if include == cur_include: continue
88 out.Write('#include "%s"\n' % include)
89
90 # Generate all interface defines
91 out.Write('\n')
92 for node in filenode.GetListOf('Interface'):
93 out.Write( cgen.InterfaceDefs(node) )
94
95 # Generate the @file comment
96 out.Write('%s\n' % cgen.Comment(fileinfo, prefix='*\n @file'))
97 57
98 # Generate definitions. 58 # Generate definitions.
99 last_group = None 59 last_group = None
100 for node in filenode.GetChildren()[2:]: 60 top_types = ['Typedef', 'Interface', 'Struct', 'Enum', 'Inline']
101 # If we are part of a group comment marker... 61 for node in filenode.GetListOf(*top_types):
102 if last_group and last_group != node.cls: 62 # Skip if this node is not in this release
103 pre = cgen.CommentLines(['*',' @}', '']) + '\n' 63 if not node.InReleases(releases):
104 else: 64 print "Skiping %s" % node
105 pre = '\n' 65 continue
106 66
107 if node.cls in ['Typedef', 'Interface', 'Struct', 'Enum']: 67 # End/Start group marker
108 if last_group != node.cls: 68 if do_comments:
109 pre += cgen.CommentLines(['*',' @addtogroup %ss' % node.cls, ' @{', '']) 69 last_group = WriteGroupMarker(out, node, last_group)
110 last_group = node.cls
111 else:
112 last_group = None
113 70
114 if node.IsA('Comment'): 71 if node.IsA('Inline'):
115 item = '%s\n\n' % cgen.Comment(node) 72 item = node.GetProperty('VALUE')
116 elif node.IsA('Inline'): 73 # If 'C++' use __cplusplus wrapper
117 if not inline: continue
118 if node.GetName() == 'cc': 74 if node.GetName() == 'cc':
119 item = cgen.Define(node, prefix=pref, comment=True)
120 item = '#ifdef __cplusplus\n%s\n#endif // __cplusplus\n\n' % item 75 item = '#ifdef __cplusplus\n%s\n#endif // __cplusplus\n\n' % item
121 elif node.GetName() == 'c': 76 # If not C++ or C, then skip it
122 item = cgen.Define(node, prefix=pref, comment=True) 77 elif not node.GetName() == 'c':
78 continue
79 if item: out.Write(item)
80 continue
81
82 #
83 # Otherwise we are defining a file level object, so generate the
84 # correct document notation.
85 #
86 item = cgen.Define(node, releases, prefix=pref, comment=True)
87 if not item: continue
88 asize = node.GetProperty('assert_size()')
89 if asize:
90 name = '%s%s' % (pref, node.GetName())
91 if node.IsA('Struct'):
92 form = 'PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(%s, %s);\n'
123 else: 93 else:
124 continue 94 form = 'PP_COMPILE_ASSERT_SIZE_IN_BYTES(%s, %s);\n'
125 if not item: continue 95 item += form % (name, asize[0])
126 else:
127 #
128 # Otherwise we are defining a file level object, so generate the
129 # correct document notation.
130 #
131 item = cgen.Define(node, prefix=pref, comment=True)
132 if not item: continue
133 asize = node.GetProperty('assert_size()')
134 if asize:
135 name = '%s%s' % (pref, node.GetName())
136 if node.IsA('Struct'):
137 form = 'PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(%s, %s);\n'
138 else:
139 form = 'PP_COMPILE_ASSERT_SIZE_IN_BYTES(%s, %s);\n'
140 item += form % (name, asize[0])
141 96
142 if item: out.Write('%s%s' % (pre, item)) 97 if item: out.Write(item)
143 if last_group: 98 if last_group:
144 out.Write(cgen.CommentLines(['*',' @}', '']) + '\n') 99 out.Write(CommentLines(['*',' @}', '']) + '\n')
145 100
146 out.Write('#endif /* %s */\n\n' % def_guard)
147 return out.Close()
148 101
149 class HGen(Generator): 102 class HGen(GeneratorByFile):
150 def __init__(self): 103 def __init__(self):
151 Generator.__init__(self, 'C Header', 'cgen', 'Generate the C headers.') 104 Generator.__init__(self, 'C Header', 'cgen', 'Generate the C headers.')
152 105
153 def GenerateVersion(self, ast, release, options): 106 def GetMacro(self, node):
154 outdir = GetOption('dstroot') 107 name = node.GetName()
155 skipList= [] 108 name = name.upper()
156 prefix = '' 109 return "%s_INTERFACE" % name
157 cfile = None
158 cnt = 0
159 110
160 for filenode in ast.GetListOf('File'): 111 def GetDefine(self, name, value):
161 if GetOption('verbose'): 112 out = '#define %s %s' % (name, value)
162 print "Working on %s" % filenode 113 if len(out) > 80:
114 out = '#define %s \\\n %s' % (name, value)
115 return '%s\n' % out
163 116
164 # If this file has errors, skip it
165 if filenode.GetProperty('ERRORS') > 0:
166 skipList.append(filenode)
167 continue
168 117
169 if GenerateHeader(filenode, release, prefix): 118 def GetOutFile(self, filenode, options):
170 cnt = cnt + 1 119 savename = GetOutFileName(filenode, GetOption('dstroot'))
120 return IDLOutFile(savename)
171 121
172 for filenode in skipList: 122 def GenerateHead(self, out, filenode, releases, options):
173 errcnt = filenode.GetProperty('ERRORS') 123 cgen = CGen()
174 ErrOut.Log('%s : Skipped because of %d errors.' % ( 124 gpath = GetOption('guard')
175 filenode.GetName(), errcnt)) 125 release = releases[0]
126 def_guard = GetOutFileName(filenode, relpath=gpath)
127 def_guard = def_guard.replace('/','_').replace('.','_').upper() + '_'
176 128
177 if skipList: 129 cright_node = filenode.GetChildren()[0]
178 return -len(skipList) 130 assert(cright_node.IsA('Copyright'))
131 fileinfo = filenode.GetChildren()[1]
132 assert(fileinfo.IsA('Comment'))
179 133
180 if GetOption('diff'): 134 out.Write('%s\n' % cgen.Copyright(cright_node))
181 return -cnt 135 out.Write('/* From %s modified %s. */\n\n'% (
182 return cnt 136 filenode.GetProperty('NAME'), filenode.GetProperty('DATETIME')))
137 out.Write('#ifndef %s\n#define %s\n\n' % (def_guard, def_guard))
138 # Generate set of includes
139
140 deps = set()
141 for release in releases:
142 deps |= filenode.GetDeps(release)
143
144 includes = set([])
145 for dep in deps:
146 depfile = dep.GetProperty('FILE')
147 if depfile:
148 includes.add(depfile)
149 includes = [GetOutFileName(include, relpath=gpath) for include in includes]
150 includes.append('ppapi/c/pp_macros.h')
151
152 # Assume we need stdint if we "include" C or C++ code
153 if filenode.GetListOf('Include'):
154 includes.append('ppapi/c/pp_stdint.h')
155
156 includes = sorted(set(includes))
157 cur_include = GetOutFileName(filenode, relpath=gpath)
158 for include in includes:
159 if include == cur_include: continue
160 out.Write('#include "%s"\n' % include)
161
162 # Generate all interface defines
163 out.Write('\n')
164 for node in filenode.GetListOf('Interface'):
165 idefs = ''
166 name = node.GetName()
167 macro = node.GetProperty('macro')
168 if not macro:
169 macro = self.GetMacro(node)
170 label = node.GetLabel()
171 if label:
172 for vers in label.versions:
173 strver = str(vers).replace('.', '_')
174 idefs += self.GetDefine('%s_%s' % (macro, strver),
175 '"%s;%s"' % (name, vers))
176 if label.GetRelease(vers) == releases[-1]:
177 idefs += self.GetDefine(macro, '%s_%s' % (macro, strver))
178 idefs += '\n'
179 out.Write(idefs)
180
181 # Generate the @file comment
182 out.Write('%s\n' % Comment(fileinfo, prefix='*\n @file'))
183
184 def GenerateBody(self, out, filenode, releases, options):
185 GenerateHeader(out, filenode, releases)
186
187 def GenerateTail(self, out, filenode, releases, options):
188 gpath = GetOption('guard')
189 def_guard = GetOutFileName(filenode, relpath=gpath)
190 def_guard = def_guard.replace('/','_').replace('.','_').upper() + '_'
191 out.Write('#endif /* %s */\n\n' % def_guard)
183 192
184 193
185 hgen = HGen() 194 hgen = HGen()
186 195
187 def Main(args): 196 def Main(args):
188 # Default invocation will verify the golden files are unchanged. 197 # Default invocation will verify the golden files are unchanged.
198 failed = 0
189 if not args: 199 if not args:
190 args = ['--wnone', '--diff', '--test', '--dstroot=.'] 200 args = ['--wnone', '--diff', '--test', '--dstroot=.']
191 201
192 ParseOptions(args) 202 ParseOptions(args)
203
193 idldir = os.path.split(sys.argv[0])[0] 204 idldir = os.path.split(sys.argv[0])[0]
194 idldir = os.path.join(idldir, 'test_cgen', '*.idl') 205 idldir = os.path.join(idldir, 'test_cgen', '*.idl')
195 filenames = glob.glob(idldir) 206 filenames = glob.glob(idldir)
207 ast = ParseFiles(filenames)
208 if hgen.GenerateRelease(ast, 'M14', {}):
209 print "Golden file for M14 failed."
210 failed = 1
211 else:
212 print "Golden file for M14 passed."
213
214
215 idldir = os.path.split(sys.argv[0])[0]
216 idldir = os.path.join(idldir, 'test_cgen_range', '*.idl')
217 filenames = glob.glob(idldir)
196 218
197 ast = ParseFiles(filenames) 219 ast = ParseFiles(filenames)
198 return hgen.GenerateVersion(ast, 'M14', {}) 220 if hgen.GenerateRange(ast, ['M13', 'M14', 'M15'], {}):
221 print "Golden file for M13-M15 failed."
222 failed =1
223 else:
224 print "Golden file for M13-M15 passed."
225
226 return failed
199 227
200 if __name__ == '__main__': 228 if __name__ == '__main__':
201 retval = Main(sys.argv[1:]) 229 retval = Main(sys.argv[1:])
202 sys.exit(retval) 230 sys.exit(retval)
203 231
OLDNEW
« no previous file with comments | « ppapi/generators/idl_ast.py ('k') | ppapi/generators/idl_c_proto.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698