From b3c51705f4a27b1a30e9e3dfa29fb8f01a22ca9b Mon Sep 17 00:00:00 2001 From: "pius.lee" Date: Wed, 7 Jan 2015 21:33:12 +0900 Subject: [PATCH] [Tool] add module skeletone generator [Verification] test skeletone code with every Web IDL module. Change-Id: Id6046fdd97efd6a40f136e5ecefffe0b41c73dd3 Signed-off-by: pius.lee --- tools/WAPIOven.py | 291 +++++++++ tools/WebIDL.py | 1247 ++++++++++++++++++++++++++++++++++++ tools/tpl/tpl_api.js | 229 +++++++ tools/tpl/tpl_extension.cc | 25 + tools/tpl/tpl_extension.h | 20 + tools/tpl/tpl_instance.cc | 127 ++++ tools/tpl/tpl_instance.h | 31 + 7 files changed, 1970 insertions(+) create mode 100644 tools/WAPIOven.py create mode 100644 tools/WebIDL.py create mode 100644 tools/tpl/tpl_api.js create mode 100644 tools/tpl/tpl_extension.cc create mode 100644 tools/tpl/tpl_extension.h create mode 100644 tools/tpl/tpl_instance.cc create mode 100644 tools/tpl/tpl_instance.h diff --git a/tools/WAPIOven.py b/tools/WAPIOven.py new file mode 100644 index 00000000..40cb50c3 --- /dev/null +++ b/tools/WAPIOven.py @@ -0,0 +1,291 @@ +import WebIDL +from collections import OrderedDict +from Queue import Queue +import jinja2 + +cppPrimitiveMap = { + 'DOMString':'std::string', + 'object':'picojson::object', + 'boolean':'bool', + 'byte':'double', + 'octet':'double', + 'short':'double', + 'long':'double', + 'long long': 'double', + 'unsigned short': 'double', + 'unsigned long': 'double', + 'unsigned long long': 'double', + 'float':'double', + 'double':'double'} + +class IndentPrintable(object): + def __init__(self, isIndent=True, tabstep=2, ignoreLF=False): + self.moduleName = moduleName + self.depth = 0 + self.buf = '' + self.isIndent = isIndent + self.tabstep=tabstep + self.ignoreLF = ignoreLF + + def indepth(self): + self.depth+=1 + + def outdepth(self): + self.depth-=1 + + def indent(self): + if self.isIndent: + return ''.ljust(self.depth * self.tabstep) + else: + return '' + + def dprint(self, string): + for s in string.split('\n'): + self.buf += self.indent() + self.buf += s + if not self.ignoreLF: + self.buf += '\n' + else: + self.buf += ' ' + + def output(self): + return self.buf + +class Compiler(IndentPrintable): + + def __init__(self, tree, indent=True, tabstep=4, ignoreLF=False): + super(Compiler, self).__init__(indent, tabstep, ignoreLF) + self.tree = tree + self.tplEnv = jinja2.Environment( + loader=jinja2.FileSystemLoader('./tpl'), + trim_blocks=True, + lstrip_blocks=True) + + TODOSTR = "todo:" + + def todo(self, formatstring): + self.dprint(("// %s " % Compiler.TODOSTR) +formatstring) + + def prepare(self): + self.ctx = dict() + self.ctx['modules'] = [] + self.ctx['implementedObject'] = None + self.ctx['implementedClass'] = None + self.ctx['export'] = dict() + self.ctx['callback'] = dict() + self.ctx['dictionary'] = dict() + self.ctx['enum'] = dict() + self.ctx['typedef'] = dict() + self.ctx['activeObjects'] = set() + self.ctx['implementOperations'] = dict() + self.ctx['exportedInterface'] = [] + self.ctx['Tizen'] = [] + self.ctx['Window'] = [] + self.ctx['cmdtable'] = dict() + + self.q = Queue() + + for m in self.tree: + self.q.put(m) + + while self.q.qsize()>0: + self.prepareX(self.q.get()) + + for m in self.tree: + for iface in m.getTypes('Interface'): + if iface.inherit in [x.name for x in self.ctx['exportedInterface']]: + iface.exported = True + if iface.name in self.ctx['callback']: + iface.isListener = True + for operation in iface.getTypes('Operation'): + if hasattr(iface, 'exported') and iface.exported: + operation.native_cmd = iface.name+'_'+operation.name + operation.native_function = iface.name+(operation.name.title()) + self.ctx['cmdtable'][operation.native_function] = operation.native_cmd + operation.argnames = [a.name for a in operation.arguments] + operation.primitiveArgs = [x for x in operation.arguments if not x.optional and x.xtype.name in cppPrimitiveMap] + for arg in operation.arguments: + if arg.xtype.name in self.ctx['enum']: + arg.isEnum = True + arg.enums = self.ctx['enum'][arg.xtype.name] + if arg.xtype.name in self.ctx['typedef']: + arg.isTypedef = True + t = self.ctx['typedef'][arg.xtype.name] + if t.union: + union_names = [t.name for t in t.union] + arg.isEnum = reduce(lambda x, y: x & y, [ x in self.ctx['enum'] for x in union_names]) + if arg.isEnum : + arg.enums = reduce(lambda x,y: x+y, [ self.ctx['enum'][x] for x in self.ctx['enum'] if x in union_names]) + arg.isTypes = reduce(lambda x, y: x & y, [ x in m.getTypes('Interface') for x in union_names]) + if arg.xtype.name in self.ctx['callback']: + arg.isListener = True + arg.listenerType = self.ctx['callback'][arg.xtype.name] + operation.async = True + m.async = True + if arg.listenerType.get('Operation', 'onsuccess'): + arg.listenerType.callbackType = 'success' + elif arg.listenerType.get('Operation', 'onerror'): + arg.listenerType.callbackType = 'error' + + for xiface in self.ctx['exportedInterface']: + if operation.returnType.name == xiface.name: + operation.returnInternal = xiface + break + + def prepareX(self, x): + if isinstance(x, WebIDL.XImplements) and (x.name in ['Tizen', 'Window']): + self.ctx['implementedClass'] = x.impl + self.ctx[x.name].append(x.impl) + impl = x.parent.get('Interface', x.impl) + impl.implements = x.name + + if isinstance(x, WebIDL.XAttribute) and isinstance(x.parent, WebIDL.XInterface): + if x.parent.name == self.ctx['implementedClass']: + self.ctx['implementedObject'] = x.name + inheritIface = x.parent.parent.get('Interface', x.xtype.name) + if inheritIface : + self.ctx[x.parent.implements] = inheritIface.name + inheritIface.exported = True + self.ctx['exportedInterface'].append(inheritIface) + + if isinstance(x, WebIDL.XInterface): + xattrs = [attr.name for attr in x.getTypes('ExtendedAttribute')] + if 'Callback' in xattrs: + self.ctx['callback'][x.name] = x + + if isinstance(x, WebIDL.XOperation): + module = x.parent.parent + if module.get('Interface', x.returnType.name): + self.ctx['activeObjects'].add(x.returnType.name) + inheritIface = module.get('Interface', x.returnType.name) + if inheritIface : + inheritIface.exported = True + self.ctx['exportedInterface'].append(inheritIface) + + if isinstance(x, WebIDL.XDictionary): + self.ctx['dictionary'][x.name] = x + + if isinstance(x, WebIDL.XTypedef): + self.ctx['typedef'][x.name] = x.xtype + + if isinstance(x, WebIDL.XEnum): + self.ctx['enum'][x.name] = x.childs + + if isinstance(x, WebIDL.XObject): + for child in x.childs: + self.q.put(child) + + TPL_API_JS = "tpl_api.js" + + def makeJSStub(self): + self.prepare() + tpl = self.tplEnv.get_template(Compiler.TPL_API_JS) + + return tpl.render({'modules':self.tree, + 'callbacks':self.ctx['callback'], + 'tizen': self.ctx['Tizen'], + 'window': self.ctx['Window'], + 'cmdtable' : self.ctx['cmdtable']}) + + + TPL_EXTENSION_H = "tpl_extension.h" + TPL_EXTENSION_CC = "tpl_extension.cc" + TPL_INSTANCE_H = "tpl_instance.h" + TPL_INSTANCE_CC = "tpl_instance.cc" + + def makeCppStubs(self, module): + extension_h = self.makeCppStub(module, Compiler.TPL_EXTENSION_H) + extension_cc = self.makeCppStub(module, Compiler.TPL_EXTENSION_CC) + instance_h = self.makeCppStub(module, Compiler.TPL_INSTANCE_H) + instance_cc = self.makeCppStub(module, Compiler.TPL_INSTANCE_CC) + + return { + module+'_extension.h':extension_h, + module+'_extension.cc':extension_cc, + module+'_instance.h':instance_h, + module+'_instance.cc':instance_cc} + + def makeCppStub(self, module, tpl_file): + tpl = self.tplEnv.get_template(tpl_file) + vals = dict() + vals['module'] = { + 'upper':module.upper(), + 'lower':module.lower(), + 'title':module.title() + } + + + #m = [m for m in self.tree if m.name.lower() == module.lower()] + m = [m for m in self.tree] + vals['moduleObj'] = m[0] if len(m)>0 else None + vals['tizen'] = self.ctx['Tizen'] + vals['window'] = self.ctx['Window'] + vals['cmdtable'] = self.ctx['cmdtable'] + + return tpl.render(vals) + +import sys +import getopt + +def printhelp(): + print '%s [-t js|cpp] [-d outdirectory] [-m modulename] webidl' % sys.argv[0] + +if __name__ == '__main__': + argv = sys.argv[1:] + try: + opts, args = getopt.getopt(argv, "ht:d:") + except getopt.GetoptError: + printhelp() + sys.exit(2) + + outDirectory = None + only = None + moduleName = None + + for opt, arg in opts: + if opt == '-h': + printhelp() + sys.exit() + elif opt == '-t': + only = arg + elif opt == '-d': + outDirectory = arg + elif opt == '-m': + moduleName = arg + + if len(args)<1: + printhelp() + sys.exit(2) + + if not moduleName: + moduleName = args[0][args[0].find('/')+1:args[0].find('.')] + + f = open(args[0]) + widl = f.read() + f.close() + + p = WebIDL.Parser() + tree = p.parse(widl) + c = Compiler(tree) + + jscode = c.makeJSStub() + cppcode = c.makeCppStubs(moduleName) + + if outDirectory: + if only != 'cpp': + f = open("%s/%s_api.js" % (outDirectory, moduleName), 'w') + f.write(jscode) + f.close() + if only != 'js': + for cc in cppcode: + f = open("%s/%s" % (outDirectory, cc), 'w') + f.write(cppcode[cc]) + f.close() + else: + if only != 'cpp': + print jscode + pass + + if only != 'js': + for cc in cppcode: + print cppcode[cc] diff --git a/tools/WebIDL.py b/tools/WebIDL.py new file mode 100644 index 00000000..25241293 --- /dev/null +++ b/tools/WebIDL.py @@ -0,0 +1,1247 @@ +import sys +from pprint import pprint + +try: + import lex + import yacc +except ImportError: + try: + from ply import lex + from ply import yacc + except ImportError: + print 'python ply is requred.' + sys.exit(1) + +class XObject(object): + def __init__(self): + self.name = "" + self.type = "" + self.typedChilds = dict() + self.extras = [] + self.parent = None + + def add(self, child): + if isinstance(child, XObject): + type = child.type + child.parent = self + else: + type = 'string' + if not self.typedChilds.has_key(type) or not self.typedChilds[type]: + self.typedChilds[type] = [] + self.typedChilds[type].append(child) + #self.typedChilds.append(child) + + @property + def childs(self): + cs = [] + for t in self.typedChilds: + cs += self.typedChilds[t] + return cs + + def getTypes(self, type): + if type in self.typedChilds: + return self.typedChilds[type] + else: + return [] + + def get(self, type, name): + tcs = self.typedChilds[type] + for o in tcs: + if o.name == name: + return o + return None + + +class XDepthPrintable(XObject): + def __init__(self): + super(XDepthPrintable, self).__init__() + self.depth = 0 + + def add(self, child): + super(XDepthPrintable, self).add(child) + if isinstance(child, XDepthPrintable): + child.depth += 1 + + +class XType(XObject): + def __init__(self, name, unions=None, array=0, nullable=None, sequence=None, unsigned=None, unrestricted=None): + super(XType, self).__init__() + self.array = array + self.nullable = nullable + self.sequence = sequence + self.unsigned = unsigned + self.unrestricted = unrestricted + self.name = name + + if isinstance(name, XType): + self.array += name.array + self.name = name.name + self.unsigned = name.unsigned if unsigned == None else False + self.sequence = name.sequence if sequence == None else False + self.nullable = name.nullable if nullable == None else False + self.unrestricted = name.unrestricted if unrestricted == None else False + + self.union = [] + if isinstance(unions, list): + for t in unions: + self.union.append(t) + + def __repr__(self): + s = "" + if self.unsigned: + s += 'unsigned ' + + s += self.name + + if self.union: + s += "(" + s += " or ".join([repr(u) for u in self.union]) + s += ")" + if self.sequence: + s = "sequence<"+s+">" + s += "?" if self.nullable else "" + for i in range(self.array): + s+= "[]" + return s + +XVoid = XType('Void') + +class XDefinition(XDepthPrintable): + def __init__(self, name, type): + super(XDefinition, self).__init__() + self.name = name + self.type = type + + def desc(self): + return "" + + def __repr__(self): + indent = "".ljust(self.depth*4) + s = indent + "<%s:%s %s>" % (self.type, self.name, self.desc()) + for ch in self.childs: + ss = indent.ljust(4) + ch if isinstance(ch, str) else repr(ch) + s += "\n" + indent + ss + return s + +class XModule(XDefinition): + def __init__(self, name): + super(XModule, self).__init__(name, 'Module') + +class XEnum(XDefinition): + def __init__(self, name): + super(XEnum, self).__init__(name, 'Enum') + +class XTypedef(XDefinition): + def __init__(self, name, xtype): + super(XTypedef, self).__init__(name, 'Typedef') + self.xtype = xtype + + def desc(self): + return "%s = %s" % (self.name, self.xtype) + +class XAttribute(XDepthPrintable): + def __init__(self, name, xtype, inherit=False, readonly=False): + super(XAttribute, self).__init__() + self.type = 'Attribute' + self.name = name + self.inherit = inherit + self.readonly = readonly + self.xtype = xtype + self.extAttr = [] + + + def __repr__(self): + indent = "".ljust(self.depth*4) + s = indent+"" % (self.name, self.xtype) + if self.readonly: + s += " readonly" + if self.inherit: + s += " inherit" + return s + +class XArgument(XDepthPrintable): + def __init__(self, name, xtype, default=None, optional=False, ellipsis=None): + super(XArgument, self).__init__() + self.name = name + self.xtype = xtype + self.default = default + self.optional = optional + self.ellipsis = ellipsis + + def __repr__(self): + s = "optional" if self.optional else "" + s += " %s" % repr(self.xtype) + if self.ellipsis: + s += " ..." + s += " %s" % self.name + if self.default: + s += " = " + self.default + + return s + +class XOperation(XDepthPrintable): + def __init__(self, name, returnType=XVoid, arguments=[], static=False, specials=[], raises=[]): + super(XOperation, self).__init__() + self.type = 'Operation' + self.name = name + self.returnType = returnType + self.static = static + self.specials = specials + self.arguments = arguments + self.raises = raises + self.extAttr = [] + + def setStatic(self, static): + self.static = static + + def addSpecial(self, sp): + self.specials.append(sp) + + def __repr__(self): + indent = "".ljust(self.depth*4) + args = ", ".join([repr(arg) for arg in self.arguments]) + return indent+"" % (self.name, args, self.returnType) + +class XExtendedAttribute(XDepthPrintable): + def __init__(self, name, identity=None, arguments=[]): + super(XExtendedAttribute,self).__init__() + self.type = "ExtendedAttribute" + self.name = name + self.identity = identity + self.arguments = arguments + + def __repr__(self): + indent = "".ljust(self.depth*4) + s = self.name + if self.identity: + s += " = %s" % self.identity + if self.arguments and len(self.arguments)>0: + s += " (" + s += ", ".join(self.arguments) + s += " )" + return indent + ""%s + +class XInterface(XDefinition): + def __init__(self, name, inherit=None): + super(XInterface, self).__init__(name, 'Interface') + self.inherit = inherit; + + def desc(self): + return (" : %s" % self.inherit) if self.inherit else "" + + +class XImplements(XDefinition): + def __init__(self, name, impl): + super(XImplements, self).__init__(name, 'Implements') + self.impl = impl + + def desc(self): + return "implements %s" % self.impl + +class XDictionaryMember(XDepthPrintable): + def __init__(self, name, xtype, default): + super(XDictionaryMember, self).__init__() + self.name = name + self.xtype = xtype + self.default = default + + def __repr__(self): + indent = "".ljust(self.depth*4) + return indent + "<%s %s = %s>" % (self.xtype, self.name, self.default) + +class XDictionary(XDefinition): + def __init__(self, name, inherit=None): + super(XDictionary, self).__init__(name, 'Dictionary') + self.inherit = inherit + + def desc(self): + return (" : %s" % self.inherit) if self.inherit else "" + +class XConst(XDepthPrintable): + def __init__(self, name, xtype, value): + super(XConst, self).__init__() + self.name = name + self.xtype = xtype + self.value = value + + def __repr__(self): + indent = "".ljust(self.depth*4) + return indent + "" % (self.xtype, self.name, self.value) + +class Parser: + def __init__(self, debug = 0, verbose = 0): + self.tokens += self.argument_name_keyword + self.predefined_types + + self.debug = debug + + self.lex = lex.lex(module = self, debug = debug) + self.yacc = yacc.yacc(module = self, debug = debug) + + self.verbose = verbose + + def trace(self, txt): + if self.verbose: + print txt + + def parse(self, webidl): + return self.yacc.parse(webidl, debug = self.debug, lexer = self.lex) + + tokens = ( + 'integer_hex', + 'integer_oct', + 'integer_dec', + 'float', + 'identifier', + 'string', + 'ellipsis', + 'scope', + 'other' + ) + + argument_name_keyword = ( + 'module', # module is removed 2012 feb 07 + 'raises', # raises is removed 2012 feb 07 + 'setraises', # setraises is removed 2012 feb 07 + 'getraises', # getraises is removed 2012 feb 07 + 'inherits', # inherits is removed 2012 feb 07 + 'attribute', + 'callback', + 'const', + 'creator', + 'deleter', + 'dictionary', + 'enum', + 'exception', + 'getter', + 'implements', + 'inherit', + 'interface', + 'legacycaller', + 'partial', + 'setter', + 'static', + 'stringifier', + 'typedef', + 'unrestricted', + 'readonly' + ) + + predefined_types = ( + 'Date', + 'DOMString', + 'Infinity', + 'NaN', + 'any', + 'boolean', + 'byte', + 'double', + 'false', + 'long', + 'null', + 'object', + 'octet', + 'or', + 'optional', + 'sequence', + 'short', + 'true', + 'unsigned', + 'void' + ) + + literals = '-,:;<=>?()[]{}' + + def t_newline(self, t): + r'\n+' + t.lexer.lineno += len(t.value) + + t_ignore_whitespace = r'[\t\n\r ]+|[\t\n\r ]*((//.*|/\*.*?\*/)[\t\n\r ]*)+' + + def t_block_comment(self, t): + r'/\*(.|\n)*?\*/' + t.lexer.lineno += t.value.count('\n') + + t_ellipsis = r'\.\.\.' + + t_scope = r'::' + + def t_integer_hex(self, t): + r'-?0[xX][0-9A-F-a-f]+' + t.value = int(t.value, 16) + return t + + def t_integer_oct(self, t): + r'-?0[0-7]+' + t.value = int(t.value, 8) + return t + + def t_integer_dec(self, t): + r'-?[1-9][0-9]*|0' + t.value = int(t.value) + return t + + ''' + def t_integer(self, t): + #r'-?(0([0-7]*|[Xx][0-9A-Fa-f]+)|[1-9][0-9]*)' + r'-?0[0-7]+|-?0[Xx][0-9A-Fa-f]+|-?[0-9][0-9]*' + z = 0 + if t.value[0] == '-': + z = 1 + + if len(t.value) > 1 and t.value[z] == '0' and (t.value[z+1] == 'x' or t.value[z+1] == 'X'): + if t.value[z+2:].find('8') and t.value[z+2:].find('9'): + t.value = int(t.value, 8) + else: + t.value = int(t.value, 16) + else: + t.value = int(t.value) + return t + ''' + + def t_float(self, t): + r'-?(([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][+-]?[0-9]+)?|[0-9]+[Ee][+-]?[0-9]+)' + t.value = float(t.value) + return t + + def t_string(self, t): + r'"[^"]*"' + t.value = t.value[1:-1] + return t + + def t_identifier(self, t): + r'[A-Z_a-z][0-9A-Z_a-z]*' + if t.value in self.argument_name_keyword + self.predefined_types: + t.type = t.value + if t.value == 'true': + t.value = True + if t.value == 'false': + t.value = False + if t.value == 'null': + t.value = None + return t + + def t_error(self, t): + print "Illegal character '%s'" % t.value[0] + t.lexer.skip(1) + + def p_Definitions(self, p): + ''' + Definitions : ExtendedAttributeList Definition Definitions + | Empty + ''' + + if len(p) > 2: + d = p[2] + for extattr in p[1]: + d.add(extattr[0]) + p[0] = [d] + p[3] + else: + p[0] = [] + + def p_Definition(self, p): + ''' + Definition : Module + | CallbackOrInterface + | Partial + | Dictionary + | Exception + | Enum + | Typedef + | ImplementsStatement + ''' + p[0] = p[1] + + def p_Module(self, p): + 'Module : module identifier "{" Definitions "}" ";"' + module = XModule(p[2]) + for d in p[4]: + module.add(d) + + p[0] = module + + def p_CallbackOrInterface(self, p): + ''' + CallbackOrInterface : callback CallbackRestOrInterface + | Interface + ''' + if len(p) > 2: + p[0] = ['callback', p[2]] + else: + p[0] = p[1] + + def p_CallbackRestOrInterface(self, p): + ''' + CallbackRestOrInterface : CallbackRest + | Interface + ''' + p[0] = p[1] + + def p_Interface(self, p): + 'Interface : interface identifier Inheritance "{" InterfaceMembers "}" ";"' + interface = XInterface(p[2], p[3]) + for member in p[5]: + interface.add(member) + p[0] = interface + + def p_Partial(self, p): + 'Partial : partial PartialDefinition' + p[1][0] = 'partial ' + p[1][0] + p[0] = p[1] + + def p_PartialDefinition(self, p): + ''' + PartialDefinition : PartialInterface + | PartialDictionary + ''' + p[0] = p[1] + + def p_PartialInterface(self, p): + 'PartialInterface : interface identifier "{" InterfaceMembers "}" ";"' + p[0] = ['interface', p[2], p[4]] + + def p_InterfaceMembers(self, p): + ''' + InterfaceMembers : ExtendedAttributeList InterfaceMember InterfaceMembers + | Empty + ''' + if len(p) > 2: + member = p[2] + for extattr in p[1]: + member.add(extattr) + p[0] = [member] + p[3] + else: + p[0] = [] + + def p_InterfaceMember(self, p): + ''' + InterfaceMember : Const + | AttributeOrOperation + ''' + p[0] = p[1] + + def p_Dictionary(self, p): + 'Dictionary : dictionary identifier Inheritance "{" DictionaryMembers "}" ";"' + dictionary = XDictionary(p[2], p[3]) + for m in p[5]: + dictionary.add(m) + p[0] = dictionary + + def p_DictionaryMembers(self, p): + ''' + DictionaryMembers : ExtendedAttributeList DictionaryMember DictionaryMembers + | Empty + ''' + if p[1] != None: + p[0] = [p[2]] + p[3] + else: + p[0] = [] + + def p_DictionaryMember(self, p): + 'DictionaryMember : Type identifier Default ";"' + p[0] = XDictionaryMember(p[2], p[1], p[3]) + + def p_PartialDictionary(self, p): + 'PartialDictionary : dictionary identifier "{" DictionaryMembers "}" ";"' + p[0] = ['dictinary', p[2], p[4]] + + def p_Default(self, p): + ''' + Default : "=" DefaultValue + | Empty + ''' + p[0] = p[1] + + def p_DefaultValue(self, p): + ''' + DefaultValue : ConstValue + | string + ''' + p[0] = p[1] + + def p_Exception(self, p): + 'Exception : exception identifier Inheritance "{" ExceptionMembers "}" ";"' + p[0] = ['exception', p[2], p[5]] + + def p_ExceptionMembers(self, p): + ''' + ExceptionMembers : ExtendedAttributeList ExceptionMember ExceptionMembers + | Empty + ''' + p[0] = [p[2]] + p[3] + + def p_Inheritance(self, p): + ''' + Inheritance : ":" identifier + | Empty + ''' + if len(p) > 2: + p[0] = p[2] + else: + p[0] = [] + + def p_Enum(self, p): + 'Enum : enum identifier "{" EnumValueList "}" ";"' + enum = XEnum(p[2]) + for e in p[4]: + enum.add(e) + p[0] = enum + + def p_EnumValueList(self, p): + 'EnumValueList : string EnumValues' + p[0] = [p[1]] + p[2] + + def p_EnumValues(self, p): + ''' + EnumValues : "," string EnumValues + | Empty + ''' + if len(p) > 2: + p[0] = [p[2]] + p[3] + else: + p[0] = [] + + def p_CallbackRest(self, p): + 'CallbackRest : identifier "=" ReturnType "{" ArgumentList "}" ";"' + p[0] = ['callback', p[1], '????'] + + def p_Typedef(self, p): + 'Typedef : typedef ExtendedAttributeList Type identifier ";"' + typedef = XTypedef(p[4], p[3]) + for exattr in p[2]: + typedef.add(exattr) + p[0] = typedef + + def p_ImplementsStatement(self, p): + 'ImplementsStatement : identifier implements identifier ";"' + p[0] = XImplements(p[1], p[3]) + + def p_Const(self, p): + 'Const : const ConstType identifier "=" ConstValue ";"' + p[0] = XConst(p[3], p[2], p[5]) + #p[0] = ['const', p[3], p[5]] + + def p_ConstValue(self, p): + ''' + ConstValue : BooleanLiteral + | FloatLiteral + | integer + | null + ''' + p[0] = p[1] + + def p_BooleanLiteral(self, p): + ''' + BooleanLiteral : true + | false + ''' + p[0] = p[1] + + def p_FloatLiteral(self, p): + ''' + FloatLiteral : float + | "-" Infinity + | Infinity + | NaN + ''' + p[0] = p[1] + + def p_integer(self, p): + ''' + integer : integer_hex + | integer_oct + | integer_dec + ''' + p[0] = p[1] + + def p_AttributeOrOperation(self, p): + ''' + AttributeOrOperation : stringifier StringifierAttributeOrOperation + | Attribute + | Operation + ''' + if len(p) > 2: + p[0] = p[2] + else: + p[0] = p[1] + + def p_StringifierAttributeOrOperation(self, p): + ''' + StringifierAttributeOrOperation : Attribute + | OperationRest + | ";" + ''' + if p[1] != ';': + p[0] = p[1] + else: + pass + + def p_Attribute(self, p): + 'Attribute : Inherit ReadOnly attribute Type identifier GetRaises SetRaises ";"' + p[0] = XAttribute(p[5], p[4], p[1], p[2]) + + def p_Inherit(self, p): + ''' + Inherit : inherit + | Empty + ''' + p[0] = p[1] + + def p_ReadOnly(self, p): + ''' + ReadOnly : readonly + | Empty + ''' + p[0] = p[1] + + def p_Operation(self, p): + 'Operation : Qualifiers OperationRest' + + operation = p[2] + operation.setStatic(p[1] == 'static') + if isinstance(p[1], list): + for sp in p[1]: + operation.addSpecial(sp) + + p[0] = operation + + + def p_Qualifiers(self, p): + ''' + Qualifiers : static + | Specials + ''' + p[0] = p[1] + + def p_Specials(self, p): + ''' + Specials : Special Specials + | Empty + ''' + if len(p) > 2: + p[0] = p[1] + p[2] + else: + p[0] = [] + + def p_Special(self, p): + ''' + Special : getter + | setter + | creator + | deleter + | legacycaller + ''' + p[0] = p[1] + + def p_GetRaises(self, p): + ''' + GetRaises : getraises ExceptionList + | Empty + ''' + if len(p) > 2: + p[0] = p[2] + else: + p[0] = [] + def p_SetRaises(self, p): + ''' + SetRaises : setraises ExceptionList + | Empty + ''' + if len(p) > 2: + p[0] = p[2] + else: + p[0] = [] + + def p_OperationRest(self, p): + 'OperationRest : ReturnType OptionalIdentifier "(" ArgumentList ")" Raises ";"' + p[0] = XOperation(p[2], p[1], p[4], False, [], p[6]) + + def p_OptionalIdentifier(self, p): + ''' + OptionalIdentifier : identifier + | Empty + ''' + p[0] = p[1] + + def p_Raises(self, p): + ''' + Raises : raises ExceptionList + | Empty + ''' + if len(p) > 2: + p[0] = p[2] + else: + p[0] = [] + + def p_ExceptionList(self, p): + 'ExceptionList : "(" ScopedNameList ")"' + p[0] = p[2] + + def p_ArgumentList(self, p): + ''' + ArgumentList : Argument Arguments + | Empty + ''' + if len(p) > 2: + p[0] = [p[1]] + p[2] + else: + p[0] = [] + + def p_Arguments(self, p): + ''' + Arguments : "," Argument Arguments + | Empty + ''' + if len(p) > 3: + p[0] = [p[2]] + p[3] + else: + p[0] = [] + + def p_Argument(self, p): + 'Argument : ExtendedAttributeList OptionalOrRequiredArgument' + p[0] = p[2] + + def p_OptionalOrRequiredArgument(self, p): + ''' + OptionalOrRequiredArgument : optional Type ArgumentName Default + | Type Ellipsis ArgumentName + ''' + if p[1] == 'optional': + p[0] = XArgument(p[3], p[2], p[4], True) + else: + p[0] = XArgument(p[3], p[1], None, False, p[2] != None) + + def p_ArgumentName(self, p): + ''' + ArgumentName : ArgumentNameKeyword + | identifier + ''' + p[0] = p[1] + + def p_Ellipsis(self, p): + ''' + Ellipsis : ellipsis + | Empty + ''' + p[0] = p[1] + + def p_ExceptionMember(self, p): + ''' + ExceptionMember : Const + | ExceptionField + ''' + p[0] = p[1] + + def p_ExceptionField(self, p): + 'ExceptionField : Type identifier ";"' + p[0] = p[2] + + def p_ExtendedAttributeList(self, p): + ''' + ExtendedAttributeList : "[" ExtendedAttribute ExtendedAttributes "]" + | Empty + ''' + if p[1] != None: + p[0] = [p[2]] + p[3] + else: + p[0] = [] + + def p_ExtendedAttributes(self, p): + ''' + ExtendedAttributes : "," ExtendedAttribute ExtendedAttributes + | Empty + ''' + if p[1] != None: + p[0] = [p[2]] + p[3] + else: + p[0] = [] + + + def p_ExtendedAttribute(self, p): + ''' + ExtendedAttribute : "(" ExtendedAttributeInner ")" ExtendedAttributeRest + | "[" ExtendedAttributeInner "]" ExtendedAttributeRest + | "{" ExtendedAttributeInner "}" ExtendedAttributeRest + | ExtendedAttributeMember ExtendedAttributeRest + ''' + if len(p) > 3: + p[0] = [p[2]] + p[4] + else: + p[0] = [p[1]] + if p[2]: p[0] += p[2] + + def p_ExtendedAttributeRest(self, p): + ''' + ExtendedAttributeRest : ExtendedAttribute + | Empty + ''' + p[0] = p[1] + + def p_ExtendedAttributeInner(self, p): + ''' + ExtendedAttributeInner : "(" ExtendedAttributeInner ")" ExtendedAttributeInner + | "[" ExtendedAttributeInner "]" ExtendedAttributeInner + | "{" ExtendedAttributeInner "}" ExtendedAttributeInner + | OtherOrComma ExtendedAttributeInner + | Empty + ''' + if p[1] == None: + p[0] = [] + elif len(p) > 3: + p[0] = [p[2]] + p[4] + else: + p[0] = [p[1]] + p[2] + + def p_Other(self, p): + ''' + Other : integer + | float + | identifier + | string + | other + | "-" + | "." + | ellipsis + | ":" + | ";" + | "<" + | "=" + | ">" + | "?" + | Date + | DOMString + | Infinity + | NaN + | any + | boolean + | byte + | double + | false + | long + | null + | object + | octet + | or + | optional + | sequence + | short + | true + | unsigned + | void + | ArgumentNameKeyword + ''' + p[0] = p[1] + + + def p_ArgumentNameKeyword(self, p): + ''' + ArgumentNameKeyword : attribute + | callback + | const + | creator + | deleter + | dictionary + | enum + | exception + | getter + | implements + | inherit + | interface + | legacycaller + | partial + | setter + | static + | stringifier + | typedef + | unrestricted + ''' + p[0] = p[1] + + def p_OtherOrComma(self, p): + ''' + OtherOrComma : ExtendedAttributeMember + | "," + ''' + if p[1] == ',': + p[0] = [] + else: + p[0] = p[1] + + def p_Type(self, p): + ''' + Type : SingleType + | UnionType TypeSuffix + ''' + + if len(p) > 2: + p[0] = XType("", p[1], p[2]['array'], p[2]['nullable']) + else: + p[0] = p[1] + + def p_SingleType(self, p): + ''' + SingleType : NonAnyType + | any TypeSuffixStartingWithArray + ''' + + if p[1] == 'any': + p[0] = XType('any', None, p[2]['array']) + else: + p[0] = p[1] + + + def p_UnionType(self, p): + 'UnionType : "(" UnionMemberType or UnionMemberType UnionMemberTypes ")"' + + p[0] = [p[2]] + [p[4]] + if p[5]: + p[0] += [p[5]] + + def p_UnionMemberType(self, p): + ''' + UnionMemberType : NonAnyType + | UnionType TypeSuffix + | any "[" "]" TypeSuffix + ''' + if len(p)>2: + if p[1] == 'any': + p[0] = XType('any', None, p[4]['array']+1, p[4]['nullable']) + else: + p[0] = [] + else: + p[0] = p[1] + + def p_UnionMemberTypes(self, p): + ''' + UnionMemberTypes : or UnionMemberType UnionMemberTypes + | Empty + ''' + if len(p) > 2: + p[0] = p[2] + p[3] + else: + p[0] = [] + + def p_NonAnyType(self, p): + ''' + NonAnyType : PrimitiveType TypeSuffix + | DOMString TypeSuffix + | identifier TypeSuffix + | sequence "<" Type ">" Null + | object TypeSuffix + | Date TypeSuffix + ''' + sequence = False + typename = p[1] + nullable = False + array = 0 + if p[1] == 'sequence': + typename = None + sequence = True + nullable = p[5] + else: + tf = p[2] + if tf: + nullable = tf['nullable'] + array = tf['array'] + + p[0] = XType(typename, None, array, nullable, sequence) + + def p_ConstType(self, p): + ''' + ConstType : PrimitiveType Null + | identifier Null + ''' + p[0] = p[1] + + def p_PrimitiveType(self, p): + ''' + PrimitiveType : UnsignedIntegerType + | UnrestrictedFloatType + | boolean + | byte + | octet + ''' + p[0] = p[1] + + def p_UnrestrictedFloatType(self, p): + ''' + UnrestrictedFloatType : unrestricted FloatType + | FloatType + ''' + if len(p) > 2: + p[0] = p[2] + p[0].unrestricted = True + else: + p[0] = p[1] + + def p_FloatType(self, p): + ''' + FloatType : float + | double + ''' + p[0] = XType(p[1], None, 0, False, False, False) + + def p_UnsignedIntegerType(self, p): + ''' + UnsignedIntegerType : unsigned IntegerType + | IntegerType + ''' + + typename = p[1] if p[1] != 'unsigned' else p[2] + p[0] = XType(typename, None, 0, False, False, p[1] == 'unsigned') + + def p_IntegerType(self, p): + ''' + IntegerType : short + | long OptionalLong + ''' + if p[1] == 'long' and p[2] != None: + p[0] = 'long long' + else: + p[0] = p[1] + + def p_OptionalLong(self, p): + ''' + OptionalLong : long + | Empty + ''' + p[0] = p[1] + + def p_TypeSuffix(self, p): + ''' + TypeSuffix : "[" "]" TypeSuffix + | "?" TypeSuffixStartingWithArray + | Empty + ''' + p[0] = {'nullable':False, 'array':0} + + if p[1]: + if p[1] == '?': + p[0]['nullable'] = True + p[0]['array'] += p[2]['array'] + if p[1] == "[" and p[2] == "]": + p[0]['array'] += 1 + p[0]['array'] += p[3]['array'] + + + + def p_TypeSuffixStartingWithArray(self, p): + ''' + TypeSuffixStartingWithArray : "[" "]" TypeSuffix + | Empty + ''' + p[0] = {'array':0} + if p[1] != None: + p[0]['array'] += 1 + if p[3]: + p[0]['array'] += p[3]['array'] + + def p_Null(self, p): + ''' + Null : "?" + | Empty + ''' + p[0] = p[1] + + def p_ReturnType(self, p): + ''' + ReturnType : Type + | void + ''' + if p[1] == 'void': + p[0] = XVoid + else: + p[0] = p[1] + + def p_ScopedNameList(self, p): + 'ScopedNameList : ScopedName ScopedNames' + p[0] = [p[1]] + p[2] + + def p_ScopedNames(self, p): + ''' + ScopedNames : "," ScopedName ScopedNames + | Empty + ''' + if len(p) > 2: + p[0] = [p[2]] + p[3] + else: + p[0] = [] + + def p_ScopedName(self, p): + ''' + ScopedName : AbsoluteScopedName + | RelativeScopedName + ''' + p[0] = p[1] + + def p_AbsoluteScopedName(self, p): + 'AbsoluteScopedName : scope identifier ScopedNameParts' + p[0] = '::' + p[2] + p[3] + + def p_RelativeScopedName(self, p): + 'RelativeScopedName : identifier ScopedNameParts' + p[0] = p[1] + p[2] + + def p_ScopedNameParts(self, p): + ''' + ScopedNameParts : scope identifier ScopedNameParts + | Empty + ''' + if len(p) > 2: + p[0] = '::' + p[2] + p[3] + else: + p[0] = "" + + def p_ExtendedAttributeNoArgs(self, p): + 'ExtendedAttributeNoArgs : identifier' + p[0] = XExtendedAttribute(p[1]) + + def p_ExtendedAttributeArgList(self, p): + 'ExtendedAttributeArgList : identifier "(" ArgumentList ")"' + p[0] = XExtendedAttribute(p[1], None, p[3]) + + def p_ExtendedAttributeIdent(self, p): + 'ExtendedAttributeIdent : identifier "=" identifier' + p[0] = XExtendedAttribute(p[1], p[3]) + + def p_ExtendedAttributeNamedArgList(self, p): + 'ExtendedAttributeNamedArgList : identifier "=" identifier "(" ArgumentList ")"' + p[0] = XExtendedAttribute(p[1], p[3], p[5]) + + def p_ExtendedAttributeMember(self, p): + ''' + ExtendedAttributeMember : ExtendedAttributeNoArgs + | ExtendedAttributeArgList + | ExtendedAttributeIdent + | ExtendedAttributeNamedArgList + ''' + p[0] = p[1] + + def p_Empty(self, p): + 'Empty :' + pass + + def p_error(self, p): + try: + raise Exception("Syntax error at '%s'" % p.value, p.lineno) + except AttributeError: + raise Exception("Syntax error") + +if __name__ == '__main__': + args = sys.argv[1:] + if len(sys.argv) > 2: + sys.exit() + + f = open(args[0]) + widl = f.read() + f.close() + + +# p = Parser(debug=1, verbose=1) + p = Parser() + + tree = p.parse(widl) + + from pprint import pprint + + pprint(tree) + diff --git a/tools/tpl/tpl_api.js b/tools/tpl/tpl_api.js new file mode 100644 index 00000000..34b21989 --- /dev/null +++ b/tools/tpl/tpl_api.js @@ -0,0 +1,229 @@ +{% for module in modules %} +// {{module.name}} + +var validator_ = xwalk.utils.validator; +var types_ = validator_.Types; + +{% set type_map = {'DOMString':'STRING', 'object':'DICTIONARY', 'Date':'PLATFORM_OBJECT', 'boolean':'BOOLEAN', 'byte':'BYTE', 'octet':'OCTET', 'short':'LONG', 'long':'LONG', 'long long': 'LONG_LONG', 'unsigned short':'UNSIGNED_LONG', 'unsigned long long':'UNSIGNED_LONG_LONG', 'float':'DOUBLE', 'double':'DOUBLE'} %} + +{% if module.async %} +var callbackId = 0; +var callbacks = {}; + +extension.setMessageListener(function(json) { + var result = JSON.parse(json); + var callback = callbacks[result['callbackId']]; + callback(result); +}); + +function nextCallbackId() { + return callbackId++; +} + +var ExceptionMap = { + 'UnknownError' : tizen.WebAPIException.UNKNOWN_ERR , + 'TypeMismatchError' : tizen.WebAPIException.TYPE_MISMATCH_ERR , + 'InvalidValuesError' : tizen.WebAPIException.INVALID_VALUES_ERR , + 'IOError' : tizen.WebAPIException.IO_ERR , + 'ServiceNotAvailableError' : tizen.WebAPIException.SERVICE_NOT_AVAILABLE_ERR , + 'SecurityError' : tizen.WebAPIException.SECURITY_ERR , + 'NetworkError' : tizen.WebAPIException.NETWORK_ERR , + 'NotSupportedError' : tizen.WebAPIException.NOT_SUPPORTED_ERR , + 'NotFoundError' : tizen.WebAPIException.NOT_FOUND_ERR , + 'InvalidAccessError' : tizen.WebAPIException.INVALID_ACCESS_ERR , + 'AbortError' : tizen.WebAPIException.ABORT_ERR , + 'QuotaExceededError' : tizen.WebAPIException.QUOTA_EXCEEDED_ERR , +} + +function callNative(cmd, args) { + var json = {'cmd':cmd, 'args':args}; + var argjson = JSON.stringify(json); + var resultString = extension.internal.sendSyncMessage(argjson) + var result = JSON.parse(resultString); + + if (typeof result !== 'object') { + throw new tizen.WebAPIException(tizen.WebAPIException.UNKNOWN_ERR); + } + + if (result['status'] == 'success') { + if(result['result']) { + return result['result']; + } + return true; + } else if (result['status'] == 'error') { + var err = result['error']; + if(err) { + if(ExceptionMap[err.name]) { + throw new tizen.WebAPIException(ExceptionMap[err.name], err.message); + } else { + throw new tizen.WebAPIException(tizen.WebAPIException.UNKNOWN_ERR, err.message); + } + } + return false; + } +} + +{% set multicallback = callback|length() > 1 %} + +function callNativeWithCallback(cmd, args, callback) { + if(callback) { + var id = nextCallbackId(); + args['callbackId'] = id; + callbacks[id] = callback; + } + + return callNative(cmd, args); +} +{% endif %} + +function SetReadOnlyProperty(obj, n, v){ + Object.defineProperty(obj, n, {value:v, writable: false}); +} + +{% for enums in module.getTypes('Enum') %} +var {{enums.name}} = { + {% for e in enums.childs %} + '{{e}}': '{{e}}'{% if not loop.last %}, {% endif %} + {% endfor %} +}; +{% endfor %} + +{% for iface in module.getTypes('Interface') %} +{% if iface.exported %} +function {{iface.name}}() { + // constructor of {{iface.name}} +} + +{% if iface.inherit %} +{{iface.name}}.prototype = new {{iface.inherit}}(); +{{iface.name}}.prototype.constructor = {{iface.name}}; +{% endif %} + +{% for operation in iface.getTypes('Operation') %} +{{iface.name}}.prototype.{{operation.name}} = function( + {%- for arg in operation.arguments -%} + {%- if not arg.optional -%} + {%- if not loop.first %}, {% endif -%} + {{arg.name}} + {%- endif -%} + {%- endfor %}) { + {% if operation.arguments %} + var args = validator_.validateArgs(arguments, [ + {% for arg in operation.arguments %} + {'name' : '{{arg.name}}', 'type': types_. + {%- if arg.isListener -%} + LISTENER, 'values' : [ + {%- for listener in arg.listenerType.getTypes('Operation') -%} + '{{listener.name}}'{% if not loop.last %}, {% endif %} + {%- endfor -%} + ] + {%- elif arg.isEnum -%} + ENUM, 'values' : [ + {%- for e in arg.enums -%} + '{{e}}' {%- if not loop.last -%}, {% endif %} + {%- endfor -%} + ] + {%- elif arg.xtype.array > 0 -%} + ARRAY + {%- elif arg.xtype.unions or arg.isTypes -%} + PLATFORM_OBJECT, 'values' : [ + {%- for union in arg.xtype.unions -%} + {{union}} {%- if not loop.last -%}, {% endif -%} + {%- endfor -%} + ] + {%- elif arg.xtype.name in type_map -%} + {{type_map[arg.xtype.name]}} + {%- else -%} + DICTIONARY + {%- endif -%} + {%- if arg.optional -%}, optional : true{% endif -%} + {%- if arg.xtype.nullable -%}, nullable : true{% endif -%} + }{% if not loop.last %}, {% endif %} + {% endfor %} + ]); + {% endif %} + + {% if operation.arguments %} + var nativeParam = { + {% for arg in operation.primitiveArgs %} + '{{arg.name}}': args.{{arg.name}}{% if not loop.last %},{% endif %} + + {% endfor %} + }; + {% for arg in operation.arguments %} + {% if arg.optional %} + if (args['{{arg.name}}']) { + nativeParam['{{arg.name}}'] = args.{{arg.name}}; + } + {% endif %} + {% endfor %} + {% endif %} + {% set successcbs = [] %} + {% set errorcbs = [] %} + try { + {% if operation.async %} + var syncResult = callNativeWithCallback('{{operation.native_cmd}}', nativeParam, function(result) { + {% for arg in operation.arguments %} + {% if arg.isListener %} + {% set cb = callbacks[arg.xtype.name] %} + {% if cb.callbackType in ['success', 'error'] %} + if (result.status == '{{cb.callbackType}}') { + {% if arg.optional %} + if (args.{{arg.name}}) { + args.{{arg.name}}.on{{cb.callbackType}}(/* {{cb.callbackType}} argument */); + } + {% else %} + args.{{arg.name}}.on{{cb.callbackType}}(/* {{cb.callbackType}} argument */); + {% endif %} + } + {% else %} + {% for cbmethod in cb.getTypes('Operation') %} + if ( /* put some condition and delete true -> */true ) { + args.{{arg.name}}.{{cbmethod.name}}(/* some argument for {{cbmethod.name}} */); + } + {% endfor %} + {% endif %} + {% endif %} + {% endfor %} + }); + {% else %} + var syncResult = callNative('{{operation.native_cmd}}', nativeParam); + {% endif %} + // if you need synchronous result from native function using 'syncResult'. + } catch(e) { + throw e; + } + + {% if operation.returnInternal %} + var returnObject = new {{operation.returnInternal.name}}(); + {% for attribute in operation.returnInternal.getTypes('Attribute') %} + {% if attribute.readonly %} + SetReadOnlyProperty(returnObject, '{{attribute.name}}', {% if attribute.name in operation.argnames -%} + {{attribute.name}}); // read only property + {%- else -%} + null); // read only property + {%- endif %} + {% else %} + returnObject.{{attribute.name}} = {% if attribute.name in operation.argnames -%} + {{attribute.name}}; + {%- else -%} + null; + {%- endif %} + {% endif %} + {% endfor %} + + return returnObject; + {% endif %} +} + +{% endfor %} + +{% endif %} +{% endfor %} + +exports = new {{tizen}}(); +{% if window %} +window.{{window}} = new {{window}}(); +{% endif %} + +{% endfor %} diff --git a/tools/tpl/tpl_extension.cc b/tools/tpl/tpl_extension.cc new file mode 100644 index 00000000..3a9a8b63 --- /dev/null +++ b/tools/tpl/tpl_extension.cc @@ -0,0 +1,25 @@ +// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "{{module.lower}}/{{module.lower}}_extension.h" + +#include "{{module.lower}}/{{module.lower}}_instance.h" + +// This will be generated from {{module.lower}}_api.js +extern const char kSource_{{module.lower}}_api[]; + +common::Extension* CreateExtension() { + return new {{module.title}}Extension; +} + +{{module.title}}Extension::{{module.title}}Extension() { + SetExtensionName("tizen.{{module.lower}}"); + SetJavaScriptAPI(kSource_{{module.lower}}_api); +} + +{{module.title}}Extension::~{{module.title}}Extension() {} + +common::Instance* {{module.title}}Extension::CreateInstance() { + return new extension::{{module.lower}}::{{module.title}}Instance; +} diff --git a/tools/tpl/tpl_extension.h b/tools/tpl/tpl_extension.h new file mode 100644 index 00000000..92d55d82 --- /dev/null +++ b/tools/tpl/tpl_extension.h @@ -0,0 +1,20 @@ +// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef {{module.upper}}_{{module.upper}}_EXTENSION_H_ +#define {{module.upper}}_{{module.upper}}_EXTENSION_H_ + +#include "common/extension.h" + +class {{module.title}}Extension : public common::Extension { + public: + {{module.title}}Extension(); + virtual ~{{module.title}}Extension(); + + private: + virtual common::Instance* CreateInstance(); +}; + +#endif // {{module.upper}}_{{module.upper}}_EXTENSION_H_ + diff --git a/tools/tpl/tpl_instance.cc b/tools/tpl/tpl_instance.cc new file mode 100644 index 00000000..511b05be --- /dev/null +++ b/tools/tpl/tpl_instance.cc @@ -0,0 +1,127 @@ +// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "{{module.lower}}/{{module.lower}}_instance.h" + +#include + +#include "common/picojson.h" +#include "common/logger.h" +#include "common/platform_exception.h" + +namespace extension { +namespace {{module.lower}} { + +namespace { +// The privileges that required in {{module.title}} API +const std::string kPrivilege{{module.title}} = ""; + +} // namespace + +using namespace common; +using namespace extension::{{module.lower}}; + +{{module.title}}Instance::{{module.title}}Instance() { + using namespace std::placeholders; + #define REGISTER_SYNC(c,x) \ + RegisterSyncHandler(c, std::bind(&{{module.title}}Instance::x, this, _1, _2)); + {% for func in cmdtable %} + REGISTER_SYNC("{{cmdtable[func]}}", {{func}}); + {% endfor %} + #undef REGISTER_SYNC +} + +{{module.title}}Instance::~{{module.title}}Instance() { +} + +{% set type_map = {'DOMString':'std::string', 'object':'picojson::object', 'boolean':'bool', 'byte':'int', 'octet':'int', 'short':'int', 'long':'double', 'long long': 'double', 'unsigned short':'int', 'unsigned long long':'double', 'float':'double', 'double':'double'} %} +{% set primitives = ['int', 'double', 'bool'] %} + +{% if moduleObj.async %} +enum {{module.title}}Callbacks { + {% for func in cmdtable %} + {{func}}Callback{% if not loop.last %}, {%+ endif %} + + {% endfor %} +}; + +static void ReplyAsync({{module.title}}Instance* instance, {{module.title}}Callbacks cbfunc, + int callbackId, bool isSuccess, picojson::object& param) { + param["callbackId"] = picojson::value(static_cast(callbackId)); + param["status"] = picojson::value(isSuccess ? "success" : "error"); + + // insert result for async callback to param + switch(cbfunc) { + {% for iface in moduleObj.getTypes('Interface') %} + {% if iface.exported %} + {% for operation in iface.getTypes('Operation') %} + case {{operation.native_function}}Callback: { + // do something... + break; + } + {% endfor %} + {% endif %} + {% endfor %} + default: { + LoggerE("Invalid Callback Type"); + return; + } + } + + picojson::value result = picojson::value(param); + + instance->PostMessage(result.serialize().c_str()); +} +{% endif %} + +#define CHECK_EXIST(args, name, out) \ + if (!args.contains(name)) {\ + ReportError(TypeMismatchException(name" is required argument"), out);\ + return;\ + } + +{% for iface in moduleObj.getTypes('Interface') %} + {% if iface.exported %} + {% for operation in iface.getTypes('Operation') %} +void {{module.title}}Instance::{{operation.native_function}}(const picojson::value& args, picojson::object& out) { + {% if operation.async %} + CHECK_EXIST(args, "callbackId", out) + {% endif %} + {% for arg in operation.arguments %} + {% if not arg.optional and type_map[arg.xtype.name] %} + CHECK_EXIST(args, "{{arg.name}}", out) + {% endif %} + {% endfor %} + + {% if operation.async %} + int callbackId = args.get("callbackId").get(); + {% endif %} + {% for arg in operation.arguments %} + {% set type = type_map[arg.xtype.name] %} + {% if type %} + {%+ if type not in primitives %}const {% endif -%} + {{type}}{% if type == 'std::string' %}&{% endif %} {{arg.name}} = args.get("{{arg.name}}").get<{{type}}>(); + {% endif %} + {% endfor %} + + // implement it + + {% if operation.async %} + // call ReplyAsync in later (Asynchronously) + {% endif %} + + // if success + // ReportSuccess(out); + // if error + // ReportError(out); +} + {% endfor %} + {% endif %} +{% endfor %} + + +#undef CHECK_EXIST + +} // namespace {{module.lower}} +} // namespace extension diff --git a/tools/tpl/tpl_instance.h b/tools/tpl/tpl_instance.h new file mode 100644 index 00000000..3e5fd69d --- /dev/null +++ b/tools/tpl/tpl_instance.h @@ -0,0 +1,31 @@ +// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef {{module.upper}}_{{module.upper}}_INSTANCE_H_ +#define {{module.upper}}_{{module.upper}}_INSTANCE_H_ + +#include "common/extension.h" + +namespace extension { +namespace {{module.lower}} { + +class {{module.title}}Instance : public common::ParsedInstance { + public: + {{module.title}}Instance(); + virtual ~{{module.title}}Instance(); + + private: + {% for iface in moduleObj.getTypes('Interface') %} + {% if iface.exported %} + {% for operation in iface.getTypes('Operation') %} + void {{operation.native_function}}(const picojson::value& args, picojson::object& out); + {% endfor %} + {% endif %} + {% endfor %} +}; + +} // namespace {{module.lower}} +} // namespace extension + +#endif // {{module.upper}}_{{module.upper}}_INSTANCE_H_ -- 2.34.1