| Index: ppapi/generators/idl_c_header.py
|
| ===================================================================
|
| --- ppapi/generators/idl_c_header.py (revision 97752)
|
| +++ ppapi/generators/idl_c_header.py (working copy)
|
| @@ -17,16 +17,14 @@
|
| from idl_option import GetOption, Option, ParseOptions
|
| from idl_outfile import IDLOutFile
|
| from idl_parser import ParseFiles
|
| -from idl_c_proto import CGen
|
| -from idl_generator import Generator
|
| +from idl_c_proto import CGen, GetNodeComments, CommentLines, Comment
|
| +from idl_generator import Generator, GeneratorByFile
|
|
|
| Option('dstroot', 'Base directory of output', default='../c')
|
| Option('guard', 'Include guard prefix', default='ppapi/c')
|
| Option('out', 'List of output files', default='')
|
|
|
| -cgen = CGen()
|
| -
|
| -def IDLToHeader(filenode, relpath=None, prefix=None):
|
| +def GetOutFileName(filenode, relpath=None, prefix=None):
|
| path, name = os.path.split(filenode.GetProperty('NAME'))
|
| name = os.path.splitext(name)[0] + '.h'
|
| if prefix: name = '%s%s' % (prefix, name)
|
| @@ -34,169 +32,199 @@
|
| if relpath: name = os.path.join(relpath, name)
|
| return name
|
|
|
| +def WriteGroupMarker(out, node, last_group):
|
| + # If we are part of a group comment marker...
|
| + if last_group and last_group != node.cls:
|
| + pre = CommentLines(['*',' @}', '']) + '\n'
|
| + else:
|
| + pre = '\n'
|
|
|
| -def GenerateHeader(filenode, release, pref, inline=True):
|
| - name = filenode.GetProperty('NAME')
|
| -# if name == 'pp_stdint.idl': return
|
| + if node.cls in ['Typedef', 'Interface', 'Struct', 'Enum']:
|
| + if last_group != node.cls:
|
| + pre += CommentLines(['*',' @addtogroup %ss' % node.cls, ' @{', ''])
|
| + last_group = node.cls
|
| + else:
|
| + last_group = None
|
| + out.Write(pre)
|
| + return last_group
|
|
|
| - # If we have an 'out' filter list, then check if we should output this file.
|
| - outlist = GetOption('out')
|
| - if outlist:
|
| - outlist = outlist.split(',')
|
| - if name not in outlist:
|
| - return
|
|
|
| - savename = IDLToHeader(filenode, relpath=GetOption('dstroot'), prefix=pref)
|
| - out = IDLOutFile(savename)
|
| -
|
| +def GenerateHeader(out, filenode, releases):
|
| gpath = GetOption('guard')
|
| - def_guard = IDLToHeader(filenode, relpath=gpath, prefix=pref)
|
| - def_guard = def_guard.replace('/','_').replace('.','_').upper() + '_'
|
| - cright_node = filenode.GetChildren()[0]
|
| - assert(cright_node.IsA('Copyright'))
|
| + cgen = CGen()
|
| + pref = ''
|
| + do_comments = True
|
|
|
| - fileinfo = filenode.GetChildren()[1]
|
| - assert(fileinfo.IsA('Comment'))
|
| -
|
| - out.Write('%s\n' % cgen.Copyright(cright_node))
|
| - out.Write('/* From %s modified %s. */\n\n'% (
|
| - filenode.GetProperty('NAME'), filenode.GetProperty('DATETIME')))
|
| - out.Write('#ifndef %s\n#define %s\n\n' % (def_guard, def_guard))
|
| -
|
| - for label in filenode.GetListOf('Label'):
|
| - if label.GetName() == GetOption('label'):
|
| - cgen.SetVersionMap(label)
|
| -
|
| - deps = filenode.GetDeps(release)
|
| - # Generate set of includes
|
| - includes = set([])
|
| - for dep in deps:
|
| - depfile = dep.GetProperty('FILE')
|
| - if depfile:
|
| - includes.add(depfile)
|
| - includes = [IDLToHeader(include, relpath=gpath) for include in includes]
|
| - includes.append('ppapi/c/pp_macros.h')
|
| -
|
| - # Assume we need stdint if we "include" C or C++ code
|
| - if filenode.GetListOf('Include'):
|
| - includes.append('ppapi/c/pp_stdint.h')
|
| -
|
| - includes = sorted(set(includes))
|
| - cur_include = IDLToHeader(filenode, relpath=gpath)
|
| - for include in includes:
|
| - if include == cur_include: continue
|
| - out.Write('#include "%s"\n' % include)
|
| -
|
| - # Generate all interface defines
|
| - out.Write('\n')
|
| - for node in filenode.GetListOf('Interface'):
|
| - out.Write( cgen.InterfaceDefs(node) )
|
| -
|
| - # Generate the @file comment
|
| - out.Write('%s\n' % cgen.Comment(fileinfo, prefix='*\n @file'))
|
| -
|
| # Generate definitions.
|
| last_group = None
|
| - for node in filenode.GetChildren()[2:]:
|
| - # If we are part of a group comment marker...
|
| - if last_group and last_group != node.cls:
|
| - pre = cgen.CommentLines(['*',' @}', '']) + '\n'
|
| - else:
|
| - pre = '\n'
|
| + top_types = ['Typedef', 'Interface', 'Struct', 'Enum', 'Inline']
|
| + for node in filenode.GetListOf(*top_types):
|
| + # Skip if this node is not in this release
|
| + if not node.InReleases(releases):
|
| + print "Skiping %s" % node
|
| + continue
|
|
|
| - if node.cls in ['Typedef', 'Interface', 'Struct', 'Enum']:
|
| - if last_group != node.cls:
|
| - pre += cgen.CommentLines(['*',' @addtogroup %ss' % node.cls, ' @{', ''])
|
| - last_group = node.cls
|
| - else:
|
| - last_group = None
|
| + # End/Start group marker
|
| + if do_comments:
|
| + last_group = WriteGroupMarker(out, node, last_group)
|
|
|
| - if node.IsA('Comment'):
|
| - item = '%s\n\n' % cgen.Comment(node)
|
| - elif node.IsA('Inline'):
|
| - if not inline: continue
|
| + if node.IsA('Inline'):
|
| + item = node.GetProperty('VALUE')
|
| + # If 'C++' use __cplusplus wrapper
|
| if node.GetName() == 'cc':
|
| - item = cgen.Define(node, prefix=pref, comment=True)
|
| item = '#ifdef __cplusplus\n%s\n#endif // __cplusplus\n\n' % item
|
| - elif node.GetName() == 'c':
|
| - item = cgen.Define(node, prefix=pref, comment=True)
|
| - else:
|
| + # If not C++ or C, then skip it
|
| + elif not node.GetName() == 'c':
|
| continue
|
| - if not item: continue
|
| - else:
|
| - #
|
| - # Otherwise we are defining a file level object, so generate the
|
| - # correct document notation.
|
| - #
|
| - item = cgen.Define(node, prefix=pref, comment=True)
|
| - if not item: continue
|
| - asize = node.GetProperty('assert_size()')
|
| - if asize:
|
| - name = '%s%s' % (pref, node.GetName())
|
| - if node.IsA('Struct'):
|
| - form = 'PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(%s, %s);\n'
|
| - else:
|
| - form = 'PP_COMPILE_ASSERT_SIZE_IN_BYTES(%s, %s);\n'
|
| - item += form % (name, asize[0])
|
| + if item: out.Write(item)
|
| + continue
|
|
|
| - if item: out.Write('%s%s' % (pre, item))
|
| + #
|
| + # Otherwise we are defining a file level object, so generate the
|
| + # correct document notation.
|
| + #
|
| + item = cgen.Define(node, releases, prefix=pref, comment=True)
|
| + if not item: continue
|
| + asize = node.GetProperty('assert_size()')
|
| + if asize:
|
| + name = '%s%s' % (pref, node.GetName())
|
| + if node.IsA('Struct'):
|
| + form = 'PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(%s, %s);\n'
|
| + else:
|
| + form = 'PP_COMPILE_ASSERT_SIZE_IN_BYTES(%s, %s);\n'
|
| + item += form % (name, asize[0])
|
| +
|
| + if item: out.Write(item)
|
| if last_group:
|
| - out.Write(cgen.CommentLines(['*',' @}', '']) + '\n')
|
| + out.Write(CommentLines(['*',' @}', '']) + '\n')
|
|
|
| - out.Write('#endif /* %s */\n\n' % def_guard)
|
| - return out.Close()
|
|
|
| -class HGen(Generator):
|
| +class HGen(GeneratorByFile):
|
| def __init__(self):
|
| Generator.__init__(self, 'C Header', 'cgen', 'Generate the C headers.')
|
|
|
| - def GenerateVersion(self, ast, release, options):
|
| - outdir = GetOption('dstroot')
|
| - skipList= []
|
| - prefix = ''
|
| - cfile = None
|
| - cnt = 0
|
| + def GetMacro(self, node):
|
| + name = node.GetName()
|
| + name = name.upper()
|
| + return "%s_INTERFACE" % name
|
|
|
| - for filenode in ast.GetListOf('File'):
|
| - if GetOption('verbose'):
|
| - print "Working on %s" % filenode
|
| + def GetDefine(self, name, value):
|
| + out = '#define %s %s' % (name, value)
|
| + if len(out) > 80:
|
| + out = '#define %s \\\n %s' % (name, value)
|
| + return '%s\n' % out
|
|
|
| - # If this file has errors, skip it
|
| - if filenode.GetProperty('ERRORS') > 0:
|
| - skipList.append(filenode)
|
| - continue
|
|
|
| - if GenerateHeader(filenode, release, prefix):
|
| - cnt = cnt + 1
|
| + def GetOutFile(self, filenode, options):
|
| + savename = GetOutFileName(filenode, GetOption('dstroot'))
|
| + return IDLOutFile(savename)
|
|
|
| - for filenode in skipList:
|
| - errcnt = filenode.GetProperty('ERRORS')
|
| - ErrOut.Log('%s : Skipped because of %d errors.' % (
|
| - filenode.GetName(), errcnt))
|
| + def GenerateHead(self, out, filenode, releases, options):
|
| + cgen = CGen()
|
| + gpath = GetOption('guard')
|
| + release = releases[0]
|
| + def_guard = GetOutFileName(filenode, relpath=gpath)
|
| + def_guard = def_guard.replace('/','_').replace('.','_').upper() + '_'
|
|
|
| - if skipList:
|
| - return -len(skipList)
|
| + cright_node = filenode.GetChildren()[0]
|
| + assert(cright_node.IsA('Copyright'))
|
| + fileinfo = filenode.GetChildren()[1]
|
| + assert(fileinfo.IsA('Comment'))
|
|
|
| - if GetOption('diff'):
|
| - return -cnt
|
| - return cnt
|
| + out.Write('%s\n' % cgen.Copyright(cright_node))
|
| + out.Write('/* From %s modified %s. */\n\n'% (
|
| + filenode.GetProperty('NAME'), filenode.GetProperty('DATETIME')))
|
| + out.Write('#ifndef %s\n#define %s\n\n' % (def_guard, def_guard))
|
| + # Generate set of includes
|
|
|
| + deps = set()
|
| + for release in releases:
|
| + deps |= filenode.GetDeps(release)
|
|
|
| + includes = set([])
|
| + for dep in deps:
|
| + depfile = dep.GetProperty('FILE')
|
| + if depfile:
|
| + includes.add(depfile)
|
| + includes = [GetOutFileName(include, relpath=gpath) for include in includes]
|
| + includes.append('ppapi/c/pp_macros.h')
|
| +
|
| + # Assume we need stdint if we "include" C or C++ code
|
| + if filenode.GetListOf('Include'):
|
| + includes.append('ppapi/c/pp_stdint.h')
|
| +
|
| + includes = sorted(set(includes))
|
| + cur_include = GetOutFileName(filenode, relpath=gpath)
|
| + for include in includes:
|
| + if include == cur_include: continue
|
| + out.Write('#include "%s"\n' % include)
|
| +
|
| + # Generate all interface defines
|
| + out.Write('\n')
|
| + for node in filenode.GetListOf('Interface'):
|
| + idefs = ''
|
| + name = node.GetName()
|
| + macro = node.GetProperty('macro')
|
| + if not macro:
|
| + macro = self.GetMacro(node)
|
| + label = node.GetLabel()
|
| + if label:
|
| + for vers in label.versions:
|
| + strver = str(vers).replace('.', '_')
|
| + idefs += self.GetDefine('%s_%s' % (macro, strver),
|
| + '"%s;%s"' % (name, vers))
|
| + if label.GetRelease(vers) == releases[-1]:
|
| + idefs += self.GetDefine(macro, '%s_%s' % (macro, strver))
|
| + idefs += '\n'
|
| + out.Write(idefs)
|
| +
|
| + # Generate the @file comment
|
| + out.Write('%s\n' % Comment(fileinfo, prefix='*\n @file'))
|
| +
|
| + def GenerateBody(self, out, filenode, releases, options):
|
| + GenerateHeader(out, filenode, releases)
|
| +
|
| + def GenerateTail(self, out, filenode, releases, options):
|
| + gpath = GetOption('guard')
|
| + def_guard = GetOutFileName(filenode, relpath=gpath)
|
| + def_guard = def_guard.replace('/','_').replace('.','_').upper() + '_'
|
| + out.Write('#endif /* %s */\n\n' % def_guard)
|
| +
|
| +
|
| hgen = HGen()
|
|
|
| def Main(args):
|
| # Default invocation will verify the golden files are unchanged.
|
| + failed = 0
|
| if not args:
|
| args = ['--wnone', '--diff', '--test', '--dstroot=.']
|
|
|
| ParseOptions(args)
|
| +
|
| idldir = os.path.split(sys.argv[0])[0]
|
| idldir = os.path.join(idldir, 'test_cgen', '*.idl')
|
| filenames = glob.glob(idldir)
|
| + ast = ParseFiles(filenames)
|
| + if hgen.GenerateRelease(ast, 'M14', {}):
|
| + print "Golden file for M14 failed."
|
| + failed = 1
|
| + else:
|
| + print "Golden file for M14 passed."
|
|
|
| +
|
| + idldir = os.path.split(sys.argv[0])[0]
|
| + idldir = os.path.join(idldir, 'test_cgen_range', '*.idl')
|
| + filenames = glob.glob(idldir)
|
| +
|
| ast = ParseFiles(filenames)
|
| - return hgen.GenerateVersion(ast, 'M14', {})
|
| + if hgen.GenerateRange(ast, ['M13', 'M14', 'M15'], {}):
|
| + print "Golden file for M13-M15 failed."
|
| + failed =1
|
| + else:
|
| + print "Golden file for M13-M15 passed."
|
|
|
| + return failed
|
| +
|
| if __name__ == '__main__':
|
| retval = Main(sys.argv[1:])
|
| sys.exit(retval)
|
|
|