Ejemplo n.º 1
0
    def _add_add_complex(e: UxsdElement):
        assert isinstance(e.type, UxsdComplex)
        impl = ""
        impl += "auto {name} = capnp::Orphanage::getForMessageContaining(builder).newOrphan<ucap::{pname}>();\n".format(
            name=cpp.checked(e.name), pname=utils.to_pascalcase(e.type.name))
        impl += "{pname}_.emplace_back(std::move({name}));\n".format(
            name=cpp.checked(e.name), pname=utils.pluralize(e.type.name))
        impl += "auto child_builder = {pname}_.back().get();\n".format(
            name=e.type.name, pname=utils.pluralize(e.type.name))
        impl += _gen_set_required_attrs(e)
        impl += "return child_builder;\n"
        _add_field(
            _gen_builder(e.type), "add", e.name,
            cpp._gen_required_attribute_arg_list(_gen_builder(t),
                                                 e.type.attrs,
                                                 context="builder"), impl)

        impl = ""
        impl = "{pname}_.reserve(size);\n".format(
            pname=utils.pluralize(e.type.name))
        _add_field("void", "preallocate", e.name,
                   _gen_builder(t) + "&, size_t size", impl)

        _add_field("void", "finish", e.name,
                   _gen_builder(e.type) + " &builder", _gen_finish(e))
Ejemplo n.º 2
0
def _gen_write_complex_element(e: UxsdElement, parent: str) -> str:
    """Function to generate partial code which writes out an element with a complex type."""
    assert isinstance(e.type, UxsdComplex)
    out = ""

    def _gen_write_element_body(root: str) -> str:
        assert isinstance(e.type, UxsdComplex)
        ouv = ""
        if e.type.attrs:
            for a in e.type.attrs:
                ouv += _gen_write_attr(a, e.type.name, root, "child_context")
            if e.type.content:
                ouv += "write_{name}_capnp_type(in, {root}, child_context);\n".format(
                    root=root, name=e.type.name)
        else:
            if e.type.content:
                ouv += "write_{name}_capnp_type(in, {root}, child_context);\n".format(
                    root=root, name=e.type.name)

        return ouv

    name = cpp._gen_stub_suffix(e, parent)
    if e.many:
        plural_name = utils.pluralize(cpp._gen_stub_suffix(e, parent))
        out += "size_t num_{pname} = in.num_{name}(context);\n".format(
            name=name, pname=plural_name)
        out += "auto {name} = root.init{pname}(num_{name});\n".format(
            name=plural_name,
            pname=utils.pluralize(utils.to_pascalcase(e.name)))
        out += "for(size_t i = 0; i < num_{name}; i++) {{\n".format(
            name=plural_name)
        out += "\tauto {name} = {plural_name}[i];\n".format(
            name=name,
            plural_name=plural_name,
        )
        out += "\tauto child_context = in.get_%s(i, context);\n" % cpp._gen_stub_suffix(
            e, parent)
        out += utils.indent(_gen_write_element_body(name))
        out += "}\n"
    elif e.optional:
        out += "if(in.has_%s(context)){\n" % cpp._gen_stub_suffix(e, parent)
        out += "\tauto {name} = root.init{pname}();\n".format(
            name=name, pname=utils.to_pascalcase(e.name))
        out += "\tauto child_context = in.get_%s(context);\n" % cpp._gen_stub_suffix(
            e, parent)
        out += utils.indent(_gen_write_element_body(name))
        out += "}\n"
    else:
        out += "{\n"
        out += "\tauto child_context = in.get_%s(context);\n" % cpp._gen_stub_suffix(
            e, parent)
        out += "\tauto {name} = root.init{pname}();\n".format(
            name=name, pname=utils.to_pascalcase(e.name))
        out += utils.indent(_gen_write_element_body(name))
        out += "}\n"

    return out
Ejemplo n.º 3
0
def _gen_load_element_complex(t: UxsdElement, parent: str) -> str:
    assert isinstance(t.type, UxsdComplex)
    out = ""
    if t.many:
        out += "%s->%s.push_back(%s());\n" % (parent, utils.pluralize(
            t.name), t.type.cpp)
        out += "load_%s(node, &%s->%s.back());\n" % (t.type.name, parent,
                                                     utils.pluralize(t.name))
    else:
        out += "load_%s(node, &%s->%s);\n" % (t.type.name, parent, t.name)
        if t.optional:
            out += "%s->has_%s = 1;\n" % (parent, t.name)
    return out
Ejemplo n.º 4
0
    def _gen_finish(e: UxsdElement):
        any_many = False
        if not isinstance(e.type, UxsdComplex):
            return ""

        if isinstance(e.type.content, (UxsdDfa, UxsdAll)):
            for el in e.type.content.children:
                if el.many:
                    any_many = True
                    break

        if not any_many:
            return ""

        impl = ""
        for el in e.type.content.children:
            if el.many:
                impl += "auto {cname} = builder.init{pname}({name}_.size());\n".format(
                    cname=cpp.checked(el.name),
                    name=utils.pluralize(el.type.name),
                    pname=utils.to_pascalcase(utils.pluralize(el.name)))
                impl += "for(size_t i = 0; i < {name}_.size(); ++i) {{\n".format(
                    name=utils.pluralize(el.type.name))
                impl += "\t{cname}.adoptWithCaveats(i, std::move({name}_[i]));\n".format(
                    cname=cpp.checked(el.name),
                    name=utils.pluralize(el.type.name))
                impl += "}\n"
                impl += "{name}_.clear();\n".format(
                    name=utils.pluralize(el.type.name))
        return impl

        any_many = False
        for e2 in e.content.children:
            if isinstance(e2.type, UxsdComplex):
                if e2.many:
                    any_many = True
                    break
            elif isinstance(e2.type, UxsdSimple):
                if e2.many:
                    any_many = True
                    break
            else:
                raise TypeError(e2)

        if not any_many:
            return ""

        impl = ""

        return impl
Ejemplo n.º 5
0
 def _add_get_complex_many(e: UxsdElement):
     impl = ""
     impl += "return reader.get{pname}()[n];\n".format(
         name=e.type.name,
         pname=utils.to_pascalcase(utils.pluralize(e.name)))
     _add_field(_gen_reader(e.type), "get", e.name,
                "int n, {} &reader".format(_gen_reader(t)), impl)
Ejemplo n.º 6
0
def complex_to_capnp(t: UxsdComplex) -> str:
    fields = []
    i = 0
    for attr in t.attrs:
        name = utils.to_camelcase(attr.name)
        type = to_type(attr.type)
        if attr.default_value is not None:
            field = "\t%s @%d :%s = %s;" % (name, i, type, attr.default_value)
        else:
            field = "\t%s @%d :%s;" % (name, i, type)
        fields.append(field)
        i += 1
    if isinstance(t.content, (UxsdDfa, UxsdAll)):
        for el in t.content.children:
            name = utils.to_camelcase(el.name)
            type = to_type(el.type)
            if el.many:
                field = "\t%s @%d :List(%s);" % (utils.pluralize(name), i,
                                                 type)
                i += 1
            else:
                field = "\t%s @%d :%s;" % (name, i, type)
                i += 1
            fields.append(field)
    elif isinstance(t.content, UxsdLeaf):
        field = "\tvalue @%d :%s;" % (i, to_type(t.content.type))
        fields.append(field)
    out = "struct %s {\n" % to_type(t)
    out += "\n".join(fields)
    out += "\n}"
    return out
Ejemplo n.º 7
0
def _gen_write_complex(t: UxsdComplex, name: str, container: str) -> str:
    """Partial function to generate code which writes out a simple type."""
    out = ""
    if t.attrs:
        out += "os << \"<%s\";\n" % name
        for a in t.attrs:
            out += _gen_write_attr(a, container)
    else:
        out += "os << \"<%s\";\n" % name

    if isinstance(t.content, (UxsdDfa, UxsdAll)):
        out += "os << \">\";\n"
        for e in t.content.children:
            if e.many:
                out += "for(auto &%s: %s.%s){\n" % (utils.checked(
                    e.name), container, utils.pluralize(e.name))
                out += utils.indent(
                    _gen_write_element(e, utils.checked(e.name)))
                out += "}\n"
            else:
                new_container = "%s.%s" % (container, utils.checked(e.name))
                if e.optional:
                    out += "if(%s.has_%s){\n" % (container, e.name)
                    out += utils.indent(_gen_write_element(e, new_container))
                    out += "}\n"
                else:
                    out += _gen_write_element(e, new_container)
        out += "os << \"</%s>\";\n" % name
    elif isinstance(t.content, UxsdLeaf):
        out += "os << \">\";\n"
        out += _gen_write_simple(t.content.type, container + ".value")
        out += "os << \"</%s>\";\n" % name
    else:
        out += "os << \"/>\";\n"
    return out
Ejemplo n.º 8
0
 def _add_has(e: UxsdElement):
     impl = ""
     if e.many:
         pname = utils.to_pascalcase(utils.pluralize(e.name))
     else:
         pname = utils.to_pascalcase(e.name)
     impl += "return reader.has{pname}();\n".format(pname=pname)
     _add_field("bool", "has", e.name, _gen_reader(t) + " &reader", impl)
Ejemplo n.º 9
0
def _gen_load_element_simple(t: UxsdElement, parent: str) -> str:
    assert isinstance(t.type, UxsdSimple)
    out = ""
    if t.many:
        container = "%s->%s" % (parent, utils.pluralize(t.name))
        out += "%s.push_back(0);\n" % container
        out += _gen_load_simple(t.type, "%s.back()" % container,
                                "node.child_value()")
    else:
        container = "%s->%s" % (parent, utils.checked(t.name))
        out += _gen_load_simple(t.type, container, "node.child_value()")
        if t.optional:
            out += "%s->has_%s = 1;\n" % (parent, t.name)
    return out
Ejemplo n.º 10
0
def typedefn_from_complex_type(t: UxsdComplex) -> str:
    """Generate a C++ struct definition corresponding to a UxsdComplex.

	Example:
	/**
	 * Generated from:
	 * <xs:complexType... />
	*/
	struct t_foo {
		int bar;
		bool has_my_baz;
		t_baz my_baz;
		collapsed_vec<t_quux, quux_pool> my_quuxes;
	}
	"""
    fields = []
    for attr in t.attrs:
        fields.append("%s %s;" % (attr.type.cpp, utils.checked(attr.name)))
    if isinstance(t.content, (UxsdDfa, UxsdAll)):
        for el in t.content.children:
            if el.many:
                fields.append(
                    "collapsed_vec<%s, %s_pool> %s;" %
                    (el.type.cpp, el.type.name, utils.pluralize(el.name)))
            elif el.optional:
                fields.append("bool has_%s;" % el.name)
                fields.append("%s %s;" % (el.type.cpp, utils.checked(el.name)))
            else:
                fields.append("%s %s;" % (el.type.cpp, utils.checked(el.name)))
    elif isinstance(t.content, UxsdLeaf):
        fields.append("%s value;" % t.content.type.cpp)

    out = ""
    out += "/** Generated from:\n"
    out += utils.to_comment_body(t.source)
    out += "\n*/\n"
    out += "struct %s {\n" % t.cpp
    out += utils.indent("\n".join(fields))
    out += "\n};"
    return out
Ejemplo n.º 11
0
def render_impl_header_file(schema: UxsdSchema, cmdline: str,
                            capnp_file_name: str, interface_file_name: str,
                            input_file: str) -> str:
    out = ""
    x = {
        "version": __version__,
        "cmdline": cmdline,
        "input_file": input_file,
        "md5": utils.md5(input_file)
    }
    out += cpp_templates.header_comment.substitute(x)
    out += '#include <stdexcept>\n'
    out += '#include <vector>\n'
    out += '#include "capnp/serialize.h"\n'
    out += '#include "{}.h"\n'.format(capnp_file_name)
    out += '#include "{}"\n'.format(interface_file_name)
    out += "\n/* All uxsdcxx functions and structs live in this namespace. */\n"
    out += "namespace uxsd {\n"

    if schema.enums:
        enum_converters = [_gen_conv_enum(t) for t in schema.enums]
        out += "\n\n/* Enum conversions from uxsd to ucap */\n"
        out += "\n".join(enum_converters)

    pname = utils.to_pascalcase(schema.root_element.name)
    out += "struct Capnp{pname}ContextTypes : public Default{pname}ContextTypes {{\n\t".format(
        pname=pname)
    out += "\n\t".join(
        "using {pname}ReadContext = ucap::{pname}::Reader;".format(
            pname=utils.to_pascalcase(t.name)) for t in schema.complex_types)
    out += "\n\t"
    out += "\n\t".join(
        "using {pname}WriteContext = ucap::{pname}::Builder;".format(
            pname=utils.to_pascalcase(t.name)) for t in schema.complex_types)
    out += "\n};\n"
    out += "\n"

    out += "class Capnp{pname} : public {pname}Base<Capnp{pname}ContextTypes> {{\n\t".format(
        pname=pname)
    out += "public:\n"
    out += "\tCapnp{pname}() {{}}\n\n".format(pname=pname)

    out += "\tvoid start_load(const std::function<void(const char *)> *report_error_in) override {\n"
    out += "\t\treport_error = report_error_in;\n"
    out += "\t}\n"
    out += "\tvoid finish_load() override {}\n"
    out += "\tvoid start_write() override {}\n"
    out += "\tvoid finish_write() override {}\n"
    out += "\tvoid error_encountered(const char * file, int line, const char *message) override {\n"
    out += "\t\tstd::stringstream msg;"
    out += "\t\tmsg << message << \" occured at file: \" << file << \" line: \" << line;\n"
    out += "\t\tthrow std::runtime_error(msg.str());\n"
    out += "\t}\n"

    for t in schema.complex_types:
        out += utils.indent(
            _gen_capnp_impl(t, t.name == schema.root_element.name))
    out += "private:\n"
    out += "\tconst std::function<void(const char *)> *report_error;\n"

    for t in schema.complex_types:
        if isinstance(t.content, (UxsdDfa, UxsdAll)):
            for el in t.content.children:
                if el.many:
                    out += "\tstd::vector<capnp::Orphan<ucap::{pname}>> {name}_;\n".format(
                        pname=utils.to_pascalcase(el.type.name),
                        name=utils.pluralize(el.type.name))
    out += "};\n"

    out += "\n\n} /* namespace uxsd */\n"
    return out
Ejemplo n.º 12
0
 def _add_num(e: UxsdElement):
     impl = ""
     impl += "return reader.get{pname}().size();\n".format(
         pname=utils.to_pascalcase(utils.pluralize(e.name)))
     _add_field("size_t", "num", e.name, _gen_reader(t) + " &reader", impl)
Ejemplo n.º 13
0
def load_fn_from_complex_type(t: UxsdComplex) -> str:
    """Generate a full C++ function load_foo(&root, &out)
	which can load an XSD complex type from DOM &root into C++ object out.
	"""
    out = ""
    out += "template<class T, typename Context>\n"
    out += "inline void load_{name}_capnp_type(const ucap::{cname}::Reader &root, T &out, Context &context, const std::function<void(const char*)> * report_error, std::vector<std::pair<const char *, size_t>> * stack){{\n".format(
        name=t.name, cname=utils.to_pascalcase(t.name))

    out += "\t(void)root;\n"
    out += "\t(void)out;\n"
    out += "\t(void)context;\n"
    out += "\t(void)report_error;\n"
    out += "\t(void)stack;\n"
    out += "\n"
    for attr in t.attrs:
        if cpp.pass_at_init(attr):
            continue

        out += "\tout.set_{suffix}({data}, context);\n".format(
            suffix=cpp._gen_stub_suffix(attr, t.name),
            data=_gen_load_simple(
                attr.type, 'root.get{pname}()'.format(
                    pname=utils.to_pascalcase(attr.name))))

    if isinstance(t.content, (UxsdDfa, UxsdAll)):
        for el in t.content.children:
            name = utils.to_pascalcase(el.name)
            out += "\tstack->push_back(std::make_pair(\"get{}\", 0));\n".format(
                name)
            if el.many:
                out += "\t{\n"
                suffix = cpp._gen_stub_suffix(el, t.name)
                out += "\t\tauto data = root.get{pname}();\n".format(
                    pname=utils.pluralize(name))
                out += "\t\tout.preallocate_{suffix}(context, data.size());\n".format(
                    suffix=suffix)

                out += "\t\tfor(const auto & el : data) {\n"
                if isinstance(el.type, UxsdComplex):
                    out += "\t\t\tauto child_context = out.add_{suffix}(context{required_attrs});\n".format(
                        suffix=suffix,
                        required_attrs=_gen_required_attribute_arg_list(
                            el, 'el'))
                    out += "\t\t\tload_{suffix}_capnp_type(el, out, child_context, report_error, stack);\n".format(
                        suffix=el.type.name)
                    out += "\t\t\tout.finish_{suffix}(child_context);\n".format(
                        suffix=suffix)
                else:
                    out += "\t\t\tout.add_{suffix}({data}, context);\n".format(
                        suffix=suffix,
                        data=_gen_load_simple(el, 'el.get{}()'.format(name)))
                out += "\t\t\tstack->back().second += 1;\n"
                out += "\t\t}\n"
                out += "\t}\n"
            else:
                out += "\tif (root.has{pname}()) {{\n".format(pname=name)
                if isinstance(el.type, UxsdComplex):
                    out += "\t\tauto child_el = root.get{pname}();\n".format(
                        pname=name)
                    access = 'child_el'
                    out += "\t\tauto child_context = out.init_{suffix}(context{required_attrs});\n".format(
                        suffix=cpp._gen_stub_suffix(el, t.name),
                        required_attrs=_gen_required_attribute_arg_list(
                            el, access))
                    out += "\t\tload_{suffix}_capnp_type({access}, out, child_context, report_error, stack);\n".format(
                        access=access, suffix=el.type.name, pname=name)
                    out += "\t\tout.finish_{suffix}(child_context);\n".format(
                        suffix=cpp._gen_stub_suffix(el, t.name))
                else:
                    out += "\t\tout.init_{suffix}({data}, context);\n".format(
                        suffix=cpp._gen_stub_suffix(el, t.name),
                        data=_gen_load_simple(el,
                                              'root.get{name}()'.format(name)))
                out += "\t}\n"

            out += "\tstack->pop_back();\n"
    elif isinstance(t.content, UxsdLeaf):
        out += "\tstack->push_back(std::make_pair(\"getValue\", 0));\n"
        out += "\tout.set_{name}_value(root.getValue().cStr(), context);\n".format(
            name=t.name)
        out += "\tstack->pop_back();\n"

    out += "}\n"
    return out