diff options
author | noelallen@google.com <noelallen@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-07 01:36:01 +0000 |
---|---|---|
committer | noelallen@google.com <noelallen@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-07 01:36:01 +0000 |
commit | f0dd202ffdb5779229f52c6cfda50853778d7287 (patch) | |
tree | 3db2016e6a329cae384b3b275af5a52698ec3f85 /ppapi/generators | |
parent | 473c01ccb10d0e459a6f06784c38ed8e2bc7215b (diff) | |
download | chromium_src-f0dd202ffdb5779229f52c6cfda50853778d7287.zip chromium_src-f0dd202ffdb5779229f52c6cfda50853778d7287.tar.gz chromium_src-f0dd202ffdb5779229f52c6cfda50853778d7287.tar.bz2 |
Fix 'C' header generation
Added chidlist which provides in-order access to node children.
Extra warning information on idl_parse.
Added 'srcdir' to parser for prepending path
Added header generator
Fixed minor errors in idl_c_proto
BUG= http://codereview.chromium.org/7085014/
TEST= python idl_c_header.py --srcdir="../api" *.idl
Review URL: http://codereview.chromium.org/7056069
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@88079 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/generators')
-rw-r--r-- | ppapi/generators/idl_c_header.py | 50 | ||||
-rw-r--r-- | ppapi/generators/idl_c_proto.py | 128 | ||||
-rw-r--r-- | ppapi/generators/idl_node.py | 1 | ||||
-rw-r--r-- | ppapi/generators/idl_parser.py | 11 |
4 files changed, 133 insertions, 57 deletions
diff --git a/ppapi/generators/idl_c_header.py b/ppapi/generators/idl_c_header.py new file mode 100644 index 0000000..39ced4a --- /dev/null +++ b/ppapi/generators/idl_c_header.py @@ -0,0 +1,50 @@ +#!/usr/bin/python +# +# Copyright (c) 2011 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +""" Generator for C style prototypes and definitions """ + +import glob +import os +import sys + +from idl_log import ErrOut, InfoOut, WarnOut +from idl_node import IDLAttribute, IDLAst, IDLNode +from idl_option import GetOption, Option, ParseOptions +from idl_outfile import IDLOutFile +from idl_parser import ParseFiles +from idl_c_proto import * + +Option('hdir', 'Output directory', default='hdir') + +def Main(args): + filenames = ParseOptions(args) + ast_result = ParseFiles(filenames) + ast = ast_result.out + + ast.Dump() + for filenode in ast.GetListOf('File'): + savename = os.path.join(GetOption('hdir'), filenode.name) + out = IDLOutFile(savename) + + # Write the include guard, copyright, and file comment. + def_guard = filenode.name.replace('/','_').replace('.','_').upper() + out.Write('#ifndef %s\n#define %s\n\n' % (def_guard, def_guard)) + out.Write('%s\n' % filenode.GetOneOf('Copyright').name) + for comment in filenode.GetListOf('Comment'): + out.Write('\n%s\n' % comment.name) + + # Generate definitions. + for node in filenode.childlist[2:]: + item = Define(node, prefix='tst_') + print '>>%s<<' % item + out.Write(item) + + out.Write('\n#endif /* %s */\n\n' % def_guard) + out.Close() + +if __name__ == '__main__': + sys.exit(Main(sys.argv[1:])) + diff --git a/ppapi/generators/idl_c_proto.py b/ppapi/generators/idl_c_proto.py index c8299a6..145eff1 100644 --- a/ppapi/generators/idl_c_proto.py +++ b/ppapi/generators/idl_c_proto.py @@ -57,6 +57,15 @@ CharPtrType = { 'store': 'char*' } +# A function pointer type +FuncType = { + 'in': '$TYPEREF$', + 'inout': '$TYPEREF$', + 'out': '$TYPEREF$', + 'return': '$TYPEREF$', + 'store': '$TYPEREF$' +} + # A 'struct' is passed by pointer. StructType = { 'in': 'const $TYPEREF$*', @@ -76,6 +85,7 @@ VoidType = { } TypeMap = { + 'func': FuncType, 'enum': EnumType, 'mem_t': MemPtrType, 'str_t': CharPtrType, @@ -102,112 +112,126 @@ def GetName(node, **keyargs): # Return the array specification of the object. -def GetArrayspec(node): +def GetArrayspec(node, name): assert(node.cls == 'Array') out = '' fixed = node.GetProperty('FIXED') if fixed: - out = '[%s]' % fixed + out = '%s[%s]' % (name, fixed) else: - out = '[]' + out = '*%s' % name # Add children for child in node.GetListOf('Array'): - out += GetArrayspec(child) + out += GetArrayspec(child, name) return out # Return the <name>[<size>] form of the node. def GetNameArray(node, **keyargs): - array = '' + name = GetName(node, **keyargs) for child in node.GetListOf('Array'): - array += GetArrayspec(child) - return '%s%s' % (GetName(node, **keyargs), array) + name = GetArrayspec(child, name) + return name -# Get the 'return' type of the function. -def GetReturnType(node, **keyargs): +def GetRootType(node): root = node while root.typeinfo: + typeinfo = root.typeinfo + if root.GetOneOf('Callspec'): + return TypeMap['func'] root = root.typeinfo - typeinfo = root.name - typedata = TypeMap[typeinfo] - return node.Replace(typedata['return']) + return TypeMap[root.name] # Get the passing form of the parameter. def GetParamType(node, **keyargs): - root = node - while root.typeinfo: - root = root.typeinfo - - typeinfo = root.name - typedata = TypeMap[typeinfo] + typedata = GetRootType(node) if node.GetProperty('in'): return node.Replace(typedata['in']) if node.GetProperty('out'): return node.Replace(typedata['out']) - return node.Replace(typedata['inout']) + if node.GetProperty('inout'): + return node.Replace(typedata['inout']) + return node.GetProperty('TYPEREF') + + +# GetParam +# +# A Param signature is different than that of a Member because a Member is +# stored in the structure as declared, but the Param's signature is affected +# by how it gets passed and it's extended attributes like IN, OUT, and INOUT. +# +def GetParam(node, **keyargs): + # This may be a function. + callnode = node.GetOneOf('Callspec') + + typeref = GetParamType(node, **keyargs) + name = GetNameArray(node, **keyargs) + if callnode: + arglist = GetParamList(callnode, **keyargs) + return '%s (*%s)(%s)' % (typeref, name, ', '.join(arglist)) + return '%s %s' % (typeref, name) -# Return a list of arguments. -def GetArgList(node, **keyargs): +# GetParamList +def GetParamList(node, **keyargs): assert(node.cls == 'Callspec') out = [] for child in node.GetListOf('Param'): - out.append(GetSignature(child, **keyargs)) + out.append(GetParam(child, **keyargs)) return out -# Return the signature of this node -def GetSignature(node, **keyargs): +# DefineSignature +def DefineSignature(node, **keyargs): + # This may be a function. callnode = node.GetOneOf('Callspec') - typeinfo = node.GetProperty('TYPEREF') + typeref = node.GetProperty('TYPEREF') name = GetNameArray(node, **keyargs) - if node.cls == 'Param': - type = GetParamType(node, **keyargs) - else: - type = GetReturnType(node, **keyargs) - if callnode: - arglist = GetArgList(callnode, **keyargs) - return '%s (*%s)(%s)' % (type, name, ', '.join(arglist)) - return '%s %s' % (type, name) + arglist = GetParamList(callnode, **keyargs) + return '%s (*%s)(%s)' % (typeref, name, ', '.join(arglist)) + return '%s %s' % (typeref, name) +# Define a Member (or Function) in an interface. +def DefineMember(node, **keyargs): + return '%s;\n' % DefineSignature(node, **keyargs) + +# Define an Typedef. +def DefineTypedef(node, **keyargs): + return 'typedef %s;\n' % DefineSignature(node, **keyargs) # Define an Enum. def DefineEnum(node, **keyargs): - out = "enum %s {\n" % GetName(node, **keyargs) + out = 'enum %s {' % GetName(node, **keyargs) enumlist = [] for child in node.GetListOf('EnumItem'): value = child.GetProperty('VALUE') enumlist.append(' %s = %s' % (GetName(child), value)) - return "%s\n%s\n};\n" % (out, ',\n'.join(enumlist)) - -# Define an member Function. -def DefineFunction(node, **keyargs): - return '%s;' % GetSignature(node, **keyargs) - -# Define an Typedef. -def DefineTypedef(node, **keyargs): - return "typedef %s;\n" % GetSignature(node, **keyargs) + return '%s\n%s\n};\n' % (out, ',\n'.join(enumlist)) # Define a Struct. def DefineStruct(node, **keyargs): - out = "struct %s {\n" % (GetName(node, **keyargs)) + out = 'struct %s {\n' % (GetName(node, **keyargs)) + + # Generate Member Functions for child in node.GetListOf('Function'): - out += ' %s' % Define(child) + out += ' %s' % DefineMember(child, **keyargs) + + # Generate Member Variables for child in node.GetListOf('Member'): - out += ' %s;\n' % GetSignature(child) - out += "};" + out += ' %s' % DefineMember(child, **keyargs) + out += '};' return out -# Define a C "prototype-able" object + +# Define a top level object. def Define(node, **keyargs): declmap = { 'Enum' : DefineEnum, - 'Function' : DefineFunction, 'Interface' : DefineStruct, 'Struct' : DefineStruct, 'Typedef' : DefineTypedef, @@ -268,13 +292,13 @@ def TestFiles(filenames): for filenode in ast_result.out.GetListOf('File'): errs = TestFile(filenode) if errs: - ErrOut.Log("%s test failed with %d error(s)." % (filenode.name, errs)) + ErrOut.Log('%s test failed with %d error(s).' % (filenode.name, errs)) total_errs += errs if total_errs: - ErrOut.Log("Failed generator test.") + ErrOut.Log('Failed generator test.') else: - InfoOut.Log("Passed generator test.") + InfoOut.Log('Passed generator test.') return total_errs diff --git a/ppapi/generators/idl_node.py b/ppapi/generators/idl_node.py index 3f78c23..93b6b4a 100644 --- a/ppapi/generators/idl_node.py +++ b/ppapi/generators/idl_node.py @@ -70,6 +70,7 @@ class IDLNode(object): self.hash = None self.typeref = None self.parent = None + self.childlist = children if children: for child in children: diff --git a/ppapi/generators/idl_parser.py b/ppapi/generators/idl_parser.py index 4f38d49..d2caad1 100644 --- a/ppapi/generators/idl_parser.py +++ b/ppapi/generators/idl_parser.py @@ -41,6 +41,8 @@ Option('build_debug', 'Debug tree building.') Option('parse_debug', 'Debug parse reduction steps.') Option('token_debug', 'Debug token generation.') Option('dump_tree', 'Dump the tree.') +Option('srcdir', 'Working directory', default='.') + # # ERROR_REMAP @@ -221,9 +223,7 @@ class IDLParser(IDLLexer): Copyright = self.BuildProduction('Copyright', p, 1, None) Filedoc = self.BuildProduction('Comment', p, 2, None) - out = ListFromConcat(p[3], p[4]) - out = ListFromConcat(Filedoc, out) - p[0] = ListFromConcat(Copyright, out) + p[0] = ListFromConcat(Copyright, Filedoc, p[3], p[4]) if self.parse_debug: DumpReduction('top', p) # Build a list of top level items. @@ -620,7 +620,7 @@ class IDLParser(IDLLexer): def VerifyProduction(self, node): comment = node.GetOneOf('Comment') if node.cls in ['Interface', 'Struct', 'Function'] and not comment: - self.Warn(node, 'Missing comment.') + self.Warn(node, 'Missing comment for %s.' % node) if node.cls in ['Param']: found = False; for form in ['in', 'inout', 'out']: @@ -684,7 +684,8 @@ class IDLParser(IDLLexer): # Loads a new file into the lexer and attemps to parse it. # def ParseFile(self, filename): - data = open(filename).read() + loadname = os.path.join(GetOption('srcdir'), filename) + data = open(loadname).read() if self.verbose: InfoOut.Log("Parsing %s" % filename) try: |