Exemple #1
0
def convert_stmt(config_stmt, state_stmt):
    # Iterate the state tree
    state_substmts = grammar.sort_canonical(state_stmt.keyword,
                                            state_stmt.substmts)
    config_substmts = grammar.sort_canonical(config_stmt.keyword,
                                             config_stmt.substmts)
    for s in state_substmts:
        matching_cfg_stmts = [
            c for c in config_substmts if is_matching_stmt(c, s)
        ]
        if any(matching_cfg_stmts):
            cfg_stmt = matching_cfg_stmts[0]

            if (s.keyword in ['description', 'presence']):
                if s.arg != cfg_stmt.arg:
                    # Merge description strings.
                    cfg_stmt.arg = cfg_stmt.arg + "\n\nFROM STATE TREE (FIX ME):\n" + s.arg
            else:
                # Don't add this element (should also check type as well).
                convert_stmt(cfg_stmt, s)
        else:
            if (s.keyword != 'config'):
                # Copy the state stmt over to the config
                copied_stmt = s.copy()
                config_stmt.substmts.append(copied_stmt)
                fixup_stmt(copied_stmt)
                if copied_stmt.keyword in {
                        "container", "leaf", "leaf-list", "list", "anyxml",
                        "anydata", "choice"
                }:
                    add_substmt_canonical(
                        copied_stmt,
                        Statement(copied_stmt.top, copied_stmt,
                                  copied_stmt.pos, 'config', 'false'))
Exemple #2
0
def emit_yin(ctx, module, fd):
    fd.write('<?xml version="1.0" encoding="UTF-8"?>\n')
    fd.write('<%s name="%s"\n' % (module.keyword, module.arg))
    fd.write(' ' * len(module.keyword) + '  xmlns="%s"' % yin_namespace)

    prefix = module.search_one('prefix')
    if prefix is not None:
        namespace = module.search_one('namespace')
        fd.write('\n')
        fd.write(' ' * len(module.keyword))
        fd.write('  xmlns:' + prefix.arg + '=' + quoteattr(namespace.arg))
    for imp in module.search('import'):
        prefix = imp.search_one('prefix')
        if prefix is not None:
            rev = None
            r = imp.search_one('revision-date')
            if r is not None:
                rev = r.arg
            mod = statements.modulename_to_module(module, imp.arg, rev)
            if mod is not None:
                ns = mod.search_one('namespace')
                if ns is not None:
                    fd.write('\n')
                    fd.write(' ' * len(module.keyword))
                    fd.write('  xmlns:' + prefix.arg + '=' + quoteattr(ns.arg))
    fd.write('>\n')
    if ctx.opts.yin_canonical:
        substmts = grammar.sort_canonical(module.keyword, module.substmts)
    else:
        substmts = module.substmts
    for s in substmts:
        emit_stmt(ctx, module, s, fd, '  ', '  ')
    fd.write('</%s>\n' % module.keyword)
Exemple #3
0
def emit_stmt(ctx, stmt, fd, indent, indentstep):
    if util.is_prefixed(stmt.raw_keyword):
        (prefix, identifier) = stmt.raw_keyword
        keyword = prefix + ':' + identifier
    else:
        keyword = stmt.keyword
    fd.write(indent + keyword)
    if stmt.arg != None:
        if keyword in grammar.stmt_map:
            (arg_type, _subspec) = grammar.stmt_map[keyword]
            if arg_type in ['identifier', 'identifier-ref', 'boolean']:
                fd.write(' ' + stmt.arg)
            else:
                emit_arg(stmt.arg, fd, indent, indentstep)
        else:
            emit_arg(stmt.arg, fd, indent, indentstep)
    if len(stmt.substmts) == 0:
        fd.write(';\n')
    else:
        fd.write(' {\n')
        if ctx.opts.yang_canonical:
            substmts = grammar.sort_canonical(stmt.keyword, stmt.substmts)
        else:
            substmts = stmt.substmts
        for s in substmts:
            emit_stmt(ctx, s, fd, indent + indentstep, indentstep)
        fd.write(indent + '}\n')
Exemple #4
0
def emit_stmt(ctx, module, stmt, fd, indent, indentstep):
    if util.is_prefixed(stmt.raw_keyword):
        # this is an extension.  need to find its definition
        (prefix, identifier) = stmt.raw_keyword
        tag = prefix + ':' + identifier
        if stmt.i_extension is not None:
            ext_arg = stmt.i_extension.search_one('argument')
            if ext_arg is not None:
                yin_element = ext_arg.search_one('yin-element')
                if yin_element is not None and yin_element.arg == 'true':
                    argname = prefix + ':' + ext_arg.arg
                    argiselem = True
                else:
                    # explicit false or no yin-element given
                    argname = ext_arg.arg
                    argiselem = False
            else:
                argiselem = False
                argname = None
        else:
            argiselem = False
            argname = None
    else:
        (argname, argiselem) = syntax.yin_map[stmt.raw_keyword]
        tag = stmt.raw_keyword
    if argiselem == False or argname is None:
        if argname is None:
            attr = ''
        else:
            attr = ' ' + argname + '=' + quoteattr(stmt.arg)
        if len(stmt.substmts) == 0:
            fd.write(indent + '<' + tag + attr + '/>\n')
        else:
            fd.write(indent + '<' + tag + attr + '>\n')
            for s in stmt.substmts:
                emit_stmt(ctx, module, s, fd, indent + indentstep,
                          indentstep)
            fd.write(indent + '</' + tag + '>\n')
    else:
        fd.write(indent + '<' + tag + '>\n')
        if ctx.opts.yin_pretty_strings:
            # since whitespace is significant in XML, the current
            # code is strictly speaking incorrect.  But w/o the whitespace,
            # it looks too ugly.
            fd.write(indent + indentstep + '<' + argname + '>\n')
            fd.write(fmt_text(indent + indentstep + indentstep, stmt.arg))
            fd.write('\n' + indent + indentstep + '</' + argname + '>\n')
        else:
            fd.write(indent + indentstep + '<' + argname + '>' + \
                       escape(stmt.arg) + \
                       '</' + argname + '>\n')
        if ctx.opts.yin_canonical:
            substmts = grammar.sort_canonical(stmt.keyword, stmt.substmts)
        else:
            substmts = stmt.substmts
        for s in substmts:
            emit_stmt(ctx, module, s, fd, indent + indentstep, indentstep)
        fd.write(indent + '</' + tag + '>\n')
Exemple #5
0
def convert_module(ctx, stmt):
    if ctx.opts.yang_remove_unused_imports and stmt.keyword == 'import':
        for p in stmt.parent.i_unused_prefixes:
            if stmt.parent.i_unused_prefixes[p] == stmt:
                return

    if util.is_prefixed(stmt.raw_keyword):
        (prefix, identifier) = stmt.raw_keyword
        keyword = prefix + ':' + identifier
    else:
        keyword = stmt.keyword

    if keyword in ['module', 'submodule']:
        # Change the module name.
        module_name = stmt.arg
        stmt.arg = module_name + '-2'

        # Look for config/state containers to convert.
        if len(stmt.substmts) != 0:
            substmts = grammar.sort_canonical(stmt.keyword, stmt.substmts)
            for substmt in substmts:
                if substmt.keyword in ['namespace', 'belongs-to']:
                    substmt.arg = substmt.arg + '-2'

                if substmt.keyword == 'typedef' and substmt.arg == 'interface-state-ref':
                    stmt.substmts.remove(substmt)

                # Fix up import references to point to the combined modules.
                if (substmt.keyword in ['import', 'include']
                        and substmt.arg.startswith("ietf-") and substmt.arg
                        not in ["ietf-yang-types", "ietf-inet-types"]):
                    substmt.arg = substmt.arg + "-2"

                # Handle top level config/state containers.
                if is_config_container(substmt):
                    for s in substmts:
                        if (substmt.arg + "-state" == s.arg
                                and is_state_container(s)):
                            convert_stmt(substmt, s)
                            stmt.substmts.remove(s)

                # Handle top level augmentations of config/state containers.
                if is_state_augmentation(substmt):
                    cfg_augment = [
                        c for c in substmts if matches_cfg_augment(c, substmt)
                    ]
                    if cfg_augment:
                        cfg_stmt = cfg_augment[0]
                        convert_stmt(cfg_stmt, substmt)
                        stmt.substmts.remove(substmt)
                    else:
                        # If it is just a state augmentation then just rename the augmentation.
                        cfg_arg = matching_cfg_augment(substmt.arg)
                        substmt.arg = cfg_arg

                # Run the fixup on any groupings (e.g. to fix up type references)
                if substmt.keyword == 'grouping':
                    fixup_stmt(substmt)
Exemple #6
0
def emit_stmt(ctx, stmt, fd, level, prev_kwd_class, indent, indentstep):
    if ctx.opts.strip_module and stmt.keyword == 'import' and stmt.arg in ctx.opts.strip_module:
        return

    if isinstance(stmt.keyword, tuple):
        kw_module, _ = stmt.keyword
        if kw_module in ctx.opts.strip_module:
            return

    if ctx.opts.strip_yang_remove_unused_imports and stmt.keyword == 'import':
        for p in stmt.parent.i_unused_prefixes:
            if stmt.parent.i_unused_prefixes[p] == stmt:
                return

    if util.is_prefixed(stmt.raw_keyword):
        (prefix, identifier) = stmt.raw_keyword
        keyword = prefix + ':' + identifier
    else:
        keyword = stmt.keyword

    kwd_class = get_kwd_class(stmt.keyword)
    if ((level == 1 and kwd_class != prev_kwd_class
         and kwd_class != 'extension')
            or stmt.keyword in _keyword_with_trailing_newline):
        fd.write('\n')

    if keyword == '_comment':
        emit_comment(stmt.arg, fd, indent)
        return

    fd.write(indent + keyword)
    if stmt.arg != None:
        if keyword in grammar.stmt_map:
            (arg_type, _subspec) = grammar.stmt_map[keyword]
            if arg_type in _non_quote_arg_type:
                fd.write(' ' + stmt.arg)
            else:
                emit_arg(stmt, fd, indent, indentstep)
        else:
            emit_arg(stmt, fd, indent, indentstep)
    if len(stmt.substmts) == 0:
        fd.write(';\n')
    else:
        fd.write(' {\n')
        if ctx.opts.strip_yang_canonical:
            substmts = grammar.sort_canonical(stmt.keyword, stmt.substmts)
        else:
            substmts = stmt.substmts
        if level == 0:
            kwd_class = 'header'
        for s in substmts:
            emit_stmt(ctx, s, fd, level + 1, kwd_class, indent + indentstep,
                      indentstep)
            kwd_class = get_kwd_class(s.keyword)
        fd.write(indent + '}\n')
Exemple #7
0
def emit_yin(ctx, module, fd):
    fd.write('<?xml version="1.0" encoding="UTF-8"?>\n')
    fd.write('<%s name="%s"\n' % (module.keyword, module.arg))
    fd.write(' ' * len(module.keyword) + '  xmlns="%s"' % yin_namespace)

    prefix = module.search_one('prefix')
    if prefix is not None:
        namespace = module.search_one('namespace')
        fd.write('\n')
        fd.write(' ' * len(module.keyword))
        fd.write('  xmlns:' + prefix.arg + '=' +
                 quoteattr(namespace.arg))
    else:
        belongs_to = module.search_one('belongs-to')
        if belongs_to is not None:
            prefix = belongs_to.search_one('prefix')
            if prefix is not None:
                # read the parent module in order to find the namespace uri
                res = ctx.read_module(belongs_to.arg, extra={'no_include':True})
                if res is not None:
                    namespace = res.search_one('namespace')
                    if namespace is None or namespace.arg is None:
                        pass
                    else:
                        # success - namespace found
                        fd.write('\n')
                        fd.write(' ' * len(module.keyword))
                        fd.write('  xmlns:' + prefix.arg + '=' +
                                 quoteattr(namespace.arg))
            
    for imp in module.search('import'):
        prefix = imp.search_one('prefix')
        if prefix is not None:
            rev = None
            r = imp.search_one('revision-date')
            if r is not None:
                rev = r.arg
            mod = statements.modulename_to_module(module, imp.arg, rev)
            if mod is not None:
                ns = mod.search_one('namespace')
                if ns is not None:
                    fd.write('\n')
                    fd.write(' ' * len(module.keyword))
                    fd.write('  xmlns:' + prefix.arg + '=' +
                             quoteattr(ns.arg))
    fd.write('>\n')
    if ctx.opts.yin_canonical:
        substmts = grammar.sort_canonical(module.keyword, module.substmts)
    else:
        substmts = module.substmts
    for s in substmts:
        emit_stmt(ctx, module, s, fd, '  ', '  ')
    fd.write('</%s>\n' % module.keyword)
Exemple #8
0
def emit_stmt(ctx, module, stmt, fd, indent, indentstep, keys=[]):
    if util.is_prefixed(stmt.raw_keyword):
        # this is an extension.  need to find its definition
        (prefix, identifier) = stmt.raw_keyword
        tag = prefix + ':' + identifier
        if stmt.i_extension is not None:
            ext_arg = stmt.i_extension.search_one('argument')
            if ext_arg is not None:
                wyin_element = ext_arg.search_one('yin-element')
                if wyin_element is not None and wyin_element.arg == 'true':
                    argname = prefix + ':' + ext_arg.arg
                    argiselem = True
                else:
                    # explicit false or no yin-element given
                    argname = ext_arg.arg
                    argiselem = False
            else:
                argiselem = False
                argname = None
        else:
            argiselem = False
            argname = None
    else:
        (argname, argiselem) = syntax.yin_map[stmt.raw_keyword]
        tag = stmt.raw_keyword
    if argiselem == False or argname is None:
        if argname is None:
            attr = ''
        else:
            attr = ' ' + argname + '=' + quoteattr(stmt.arg)
        if len(stmt.substmts) == 0:
            fd.write(indent + '<' + tag + attr + '/>\n')
        else:
            if argname and argname in "name":
                fd.write(indent + ('<%s eltype="%s"' % (stmt.arg, tag)))
            else:
                fd.write(indent + '<' + tag + attr)

            used_substmts = 0
            printed_config = False
            got_keys = False
            for s in stmt.substmts:
                if not printed_config:
                    conf_val = None
                    # find predecesor with i_config or use s' i_config
                    p = s
                    if not hasattr(p, "i_config"):
                        while (not hasattr(p, "i_config")) and (p != None):
                            p = p.parent

                    # searching finished
                    if p:
                        conf_val = p.i_config.__str__().lower()
                        if conf_val == "none":
                            conf_val = "true"
                        # write config attribute
                        fd.write(' config="%s"' % conf_val)
                        printed_config = True
                    del p

                if s.raw_keyword == "key":
                    fd.write(' key="%s"' % s.arg)
                    keys = re.findall(r'\S+', s.arg)
                    got_keys = True
                if s.raw_keyword in [
                        "config", "type", "default", "description", "mandatory"
                ]:
                    # already written
                    if s.raw_keyword in "config":
                        setattr(s, "i_config", s.arg)
                    else:
                        fd.write(' %s="%s"' %
                                 (s.raw_keyword, escape2xml(s.arg)))
                    if s.raw_keyword == "type":
                        if s.arg == "enumeration":
                            fd.write(' enumval="')
                            first_written = False
                            for charg in s.substmts:
                                if first_written:
                                    fd.write(ctx.opts.enum_delim)
                                else:
                                    first_written = True
                                fd.write(charg.arg)
                            fd.write('"')
                        elif s.arg == "identityref":
                            basename = get_basename(s)
                            if identityrefs.has_key(basename):
                                fd.write(" enumval=\"")
                                sep = False
                                for i in identityrefs[basename]:
                                    if sep:
                                        fd.write("|")
                                    else:
                                        sep = True
                                    fd.write(i)
                                fd.write("\"")
                            else:
                                print "no basename %s" % basename
                        else:
                            if s.substmts:
                                #other type "attributes"
                                for charg in s.substmts:
                                    if charg.raw_keyword == "range":
                                        fd.write(' range="' + charg.arg + '"')
                    # count used substatements to know what is the rest
                    used_substmts += 1
            # mark key elements
            if stmt.arg in keys:
                fd.write(' iskey="true"')
            else:
                fd.write(' iskey="false"')
            if not got_keys:
                keys = []

            # the rest of substatements:
            if used_substmts < stmt.substmts.__len__():
                # Need to generate pair tag
                fd.write('>\n')
                for s in stmt.substmts:
                    if s.raw_keyword not in ["config", "type",\
                    "default", "description", "mandatory",\
                    "must", "when", "key"]:
                        emit_stmt(ctx, module, s, fd, indent + indentstep,
                                  indentstep, keys)
                if argname and argname in "name":
                    fd.write(indent + ('</%s>' % stmt.arg))
                else:
                    fd.write(indent + '</' + tag + '>\n')
            else:
                # Everything from child elements was used
                fd.write('/>\n')
    else:
        fd.write(indent + '<' + tag + '>\n')
        if ctx.opts.wyin_pretty_strings:
            # since whitespace is significant in XML, the current
            # code is strictly speaking incorrect.  But w/o the whitespace,
            # it looks too ugly.
            fd.write(indent + indentstep + '<' + argname + '>\n')
            fd.write(fmt_text(indent + indentstep + indentstep, stmt.arg))
            fd.write('\n' + indent + indentstep + '</' + argname + '>\n')
        else:
            try:
                fd.write(indent + indentstep + '<' + argname + '>' + \
                       escape(stmt.arg) + \
                       '</' + argname + '>\n')
            except Exception as e:
                print argname
        if ctx.opts.wyin_canonical:
            substmts = grammar.sort_canonical(stmt.keyword, stmt.substmts)
        else:
            substmts = stmt.substmts
        for s in substmts:
            emit_stmt(ctx, module, s, fd, indent + indentstep, indentstep)
        fd.write(indent + '</' + tag + '>\n')
Exemple #9
0
def add_substmt_canonical(parent_stmt, stmt):
    parent_stmt.substmts.append(stmt)
    parent_stmt.substmts = grammar.sort_canonical(parent_stmt.keyword,
                                                  parent_stmt.substmts)
Exemple #10
0
def convert_module(ctx, m_stmt):
    if ctx.opts.yang_remove_unused_imports and m_stmt.keyword == 'import':
        for p in m_stmt.parent.i_unused_prefixes:
            if m_stmt.parent.i_unused_prefixes[p] == m_stmt:
                return

    if util.is_prefixed(m_stmt.raw_keyword):
        (prefix, identifier) = m_stmt.raw_keyword
        keyword = prefix + ':' + identifier
    else:
        keyword = m_stmt.keyword

    if keyword in ['module', 'submodule']:
        # Don't change the module name, but could update the revision number?
        #module_name = m_stmt.arg
        #m_stmt.arg = module_name + '-2'

        # Look for config/state containers to convert.
        if len(m_stmt.substmts) != 0:
            m_substmts = grammar.sort_canonical(m_stmt.keyword,
                                                m_stmt.substmts)
            for substmt in m_substmts:
                if substmt.keyword in ['namespace', 'belongs-to']:
                    substmt.arg = substmt.arg + '-2'

                # Remove the interface state ref?
                # Or, is this even appropriate.
                if substmt.keyword == 'typedef' and substmt.arg == 'interface-state-ref':
                    m_stmt.substmts.remove(substmt)

                # Fix up import references to point to the combined modules.
                #if (substmt.keyword in ['import', 'include']
                #    and substmt.arg.startswith("ietf-")
                #    and substmt.arg not in ["ietf-yang-types","ietf-inet-types"]):
                #    substmt.arg = substmt.arg + "-2"

                # Handle top level config/state containers.
                if is_config_container(substmt):
                    for s in m_substmts:
                        if (s.arg == (substmt.arg + "-state")
                                and is_state_container(s)):
                            convert_stmt(substmt, s)

                            # Either remove the m_substmts, or mark it as status deprecated.
                            if IetfModelPlugin.remove_state:
                                m_stmt.substmts.remove(s)
                            else:
                                mark_stmt_deprecated(s)

                # Handle top level augmentations of config/state containers.
                if is_state_augmentation(substmt):
                    cfg_augment = [
                        c for c in m_substmts
                        if matches_cfg_augment(c, substmt)
                    ]
                    if cfg_augment:
                        cfg_stmt = cfg_augment[0]
                        convert_stmt(cfg_stmt, substmt)

                        # Either remove the m_substmts, or mark it as status deprecated.
                        if IetfModelPlugin.remove_state:
                            m_stmt.substmts.remove(substmt)
                        else:
                            mark_stmt_deprecated(substmt)
                    else:
                        # If it is just a state augmentation then just rename the augmentation.
                        cfg_arg = matching_cfg_augment(substmt.arg)
                        substmt.arg = cfg_arg

                # Run the fixup on any groupings (e.g. to fix up type references)
                if substmt.keyword == 'grouping':
                    fixup_stmt(substmt)

                # Assume that a grouping only contains state if it is has state in its name.
                if substmt.keyword == 'grouping' and "-state" in substmt.arg:
                    fixup_state_grouping(substmt)