Exemplo n.º 1
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')
Exemplo n.º 2
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')
Exemplo n.º 3
0
def _chk_stmts(ctx, pos, stmts, parent, spec, canonical):
    for stmt in stmts:
        stmt.is_grammatically_valid = False
        if not util.is_prefixed(stmt.keyword):
            chk_grammar = True
        else:
            (modname, _identifier) = stmt.keyword
            if modname in extension_modules:
                chk_grammar = True
            else:
                chk_grammar = False
        if chk_grammar == True:
            match_res = _match_stmt(ctx, stmt, spec, canonical)
        else:
            match_res = None
        if match_res is None and chk_grammar == True:
            error.err_add(ctx.errors, stmt.pos, 'UNEXPECTED_KEYWORD', 
                          util.keyword_to_str(stmt.raw_keyword))
        elif match_res is not None and chk_grammar == True:
            try:
                (arg_type, subspec) = stmt_map[stmt.keyword]
            except KeyError:
                error.err_add(ctx.errors, stmt.pos, 'UNEXPECTED_KEYWORD', 
                              util.keyword_to_str(stmt.raw_keyword))
                return
            # verify the statement's argument
            if arg_type is None and stmt.arg is not None:
                error.err_add(ctx.errors, stmt.pos,
                              'UNEXPECTED_ARGUMENT', stmt.arg)
            elif arg_type is not None and stmt.arg is None:
                error.err_add(ctx.errors, stmt.pos,
                              'EXPECTED_ARGUMENT',
                              util.keyword_to_str(stmt.keyword))
            elif (arg_type is not None and arg_type != 'string' and
                  syntax.arg_type_map[arg_type](stmt.arg) == False):
                error.err_add(ctx.errors, stmt.pos,
                              'BAD_VALUE', (stmt.arg, arg_type))
            else:
                stmt.is_grammatically_valid = True

            _chk_stmts(ctx, stmt.pos, stmt.substmts, stmt, subspec, canonical)
            spec = match_res
        else:
            # unknown extension
            stmt.is_grammatically_valid = True
            _chk_stmts(ctx, stmt.pos, stmt.substmts, stmt, 
                       [('$any', '*')], canonical)
        # update last know position
        pos = stmt.pos
    # any non-optional statements left are errors
    for (keywd, occurance) in spec:
        if occurance == '1' or occurance == '+':
            if parent is None:
                error.err_add(ctx.errors, pos, 'EXPECTED_KEYWORD',
                              util.keyword_to_str(keywd))
            else:
                error.err_add(ctx.errors, pos, 'EXPECTED_KEYWORD_2',
                              (util.keyword_to_str(keywd),
                               util.keyword_to_str(parent.raw_keyword)))
def get_kwd_class(keyword):
    if util.is_prefixed(keyword):
        return 'extension'
    else:
        try:
            return _kwd_class[keyword]
        except KeyError:
            return 'body'
Exemplo n.º 5
0
def get_kwd_class(keyword):
    if util.is_prefixed(keyword):
        return 'extension'
    else:
        try:
            return _kwd_class[keyword]
        except KeyError:
            return 'body'
Exemplo n.º 6
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')
Exemplo n.º 7
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)
Exemplo n.º 8
0
def _chk_stmts(ctx, pos, stmts, parent, spec, canonical):
    for stmt in stmts:
        stmt.is_grammatically_valid = False
        if not util.is_prefixed(stmt.keyword):
            chk_grammar = True
        else:
            (modname, _identifier) = stmt.keyword
            if modname in extension_modules:
                chk_grammar = True
            else:
                chk_grammar = False
        if chk_grammar == True:
            match_res = _match_stmt(ctx, stmt, spec, canonical)
        else:
            match_res = None
        if match_res is None and chk_grammar == True:
            error.err_add(ctx.errors, stmt.pos, 'UNEXPECTED_KEYWORD',
                          util.keyword_to_str(stmt.raw_keyword))
        elif match_res is not None and chk_grammar == True:
            try:
                (arg_type, subspec) = stmt_map[stmt.keyword]
            except KeyError:
                error.err_add(ctx.errors, stmt.pos, 'UNEXPECTED_KEYWORD',
                              util.keyword_to_str(stmt.raw_keyword))
                return
            # verify the statement's argument
            if arg_type is None and stmt.arg is not None:
                error.err_add(ctx.errors, stmt.pos, 'UNEXPECTED_ARGUMENT',
                              stmt.arg)
            elif arg_type is not None and stmt.arg is None:
                error.err_add(ctx.errors, stmt.pos, 'EXPECTED_ARGUMENT',
                              util.keyword_to_str(stmt.keyword))
            elif (arg_type is not None and arg_type != 'string'
                  and syntax.arg_type_map[arg_type](stmt.arg) == False):
                error.err_add(ctx.errors, stmt.pos, 'BAD_VALUE',
                              (stmt.arg, arg_type))
            else:
                stmt.is_grammatically_valid = True

            _chk_stmts(ctx, stmt.pos, stmt.substmts, stmt, subspec, canonical)
            spec = match_res
        else:
            # unknown extension
            stmt.is_grammatically_valid = True
            _chk_stmts(ctx, stmt.pos, stmt.substmts, stmt, [('$any', '*')],
                       canonical)
        # update last know position
        pos = stmt.pos
    # any non-optional statements left are errors
    for (keywd, occurance) in spec:
        if occurance == '1' or occurance == '+':
            if parent is None:
                error.err_add(ctx.errors, pos, 'EXPECTED_KEYWORD',
                              util.keyword_to_str(keywd))
            else:
                error.err_add(ctx.errors, pos, 'EXPECTED_KEYWORD_2',
                              (util.keyword_to_str(keywd),
                               util.keyword_to_str(parent.raw_keyword)))
Exemplo n.º 9
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')
Exemplo n.º 10
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')
Exemplo n.º 11
0
def emit_stmt(ctx, stmt, fd, level, prev_kwd_class, indent, indentstep):
    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
    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')
    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.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')
Exemplo n.º 12
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')
Exemplo n.º 13
0
def emit_stmt(ctx, module, stmt, fd, indent, indentstep):
    global revision_added

    if stmt.raw_keyword == "revision" and revision_added == False:
        revision_added = True
    elif stmt.raw_keyword == "revision" and revision_added == True:
        #Only add the latest revision
        return

    #Don't keep the following keywords as they are not used in CVL
    # stmt.raw_keyword == "revision" or
    if ((stmt.raw_keyword == "organization" or stmt.raw_keyword == "contact"
         or stmt.raw_keyword == "rpc" or stmt.raw_keyword == "notification"
         or stmt.raw_keyword == "description") or
        (len(stmt.substmts) > 0 and stmt.substmts[0].raw_keyword == "config"
         and stmt.substmts[0].arg == "false")):
        return

    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 + '/>' + new_line)
        else:
            fd.write(indent + '<' + tag + attr + '>' + new_line)
            for s in stmt.substmts:
                emit_stmt(ctx, module, s, fd, indent + indentstep, indentstep)
            fd.write(indent + '</' + tag + '>' + new_line)
    else:
        fd.write(indent + '<' + tag + '>' + new_line)
        fd.write(indent + indentstep + '<' + argname + '>' + \
                   escape(stmt.arg) + \
                   '</' + argname + '>' + new_line)
        substmts = stmt.substmts

        for s in substmts:
            emit_stmt(ctx, module, s, fd, indent + indentstep, indentstep)

        fd.write(indent + '</' + tag + '>' + new_line)
Exemplo n.º 14
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)
Exemplo n.º 15
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)
Exemplo n.º 16
0
def convert_stmt(ctx, stmt, level):
    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 == 'module':
        # Change the module name.
        module_name = stmt.arg
        stmt.arg = module_name + '-state'
        
        # Find the module prefix.
        prefix_stmt = next(x for x in stmt.substmts if x.keyword == 'prefix')
        
        # Rename the prefix statement.
        prefix = prefix_stmt.arg
        prefix_stmt.arg = prefix + '-s'
        
        # Add an import statement back to the original module.
        import_stmt = Statement(stmt.top, stmt, stmt.pos, 'import', module_name)
        add_substmt_canonical(stmt, import_stmt)
        add_substmt_canonical(import_stmt, Statement(stmt.top, import_stmt, import_stmt.pos, 'prefix', prefix))
    
        
    if keyword == 'namespace':
        stmt.arg = stmt.arg + '-state'
    
    # Remove any feature statements, reference the original module feature instead.
    if keyword == 'feature':
        stmt.parent.substmts.remove(stmt)
        
    if keyword == 'if-feature':
        fix_references(stmt, stmt.i_module.i_features)
            
    # Remove any identity statements, reference the original identity instead.
    # Identity base won't matter because they are all removed.
    if keyword == 'identity':
        stmt.parent.substmts.remove(stmt)
        
    if keyword in ('must', 'when'):
        fix_references(stmt, stmt.i_module.i_identities)
            
    if keyword == 'type' and stmt.arg == 'identityref':
        base_stmt = next(x for x in stmt.substmts if x.keyword == 'base')
        fix_references(base_stmt, stmt.i_module.i_identities)
        
    # Remove any typedef statements, reference the original typedef instead.
    if keyword == 'typedef':
        stmt.parent.substmts.remove(stmt)
        
    if keyword == 'type':
        fix_references(stmt, stmt.i_module.i_typedefs)
            
    # Remove all config statements, only the top level config false is necessary.
    if keyword == 'config':
        stmt.parent.substmts.remove(stmt)
        
    if len(stmt.substmts) != 0:
        substmts = grammar.sort_canonical(stmt.keyword, stmt.substmts)
        for s in substmts:
            convert_stmt(ctx, s, level + 1)

    # Convert top level containers from "foo" to "foo-state", and mark it as config false.
    if keyword == 'container' and stmt.parent.keyword == 'module':
        if not stmt.arg.endswith('-state'):
            stmt.arg = stmt.arg + '-state'
            add_substmt_canonical(stmt, Statement(stmt.top, stmt, stmt.pos, 'config', 'false'))
            
Exemplo n.º 17
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:
            fd.write(indent + indentstep + '<' + argname + '>' + \
                       escape(stmt.arg) + \
                       '</' + argname + '>\n')
        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')
Exemplo n.º 18
0
 def is_appinfo(keyword):
     if util.is_prefixed(keyword) == True:
         return False
     (argname, argiselem, argappinfo) = yang_keywords[keyword]
     return argappinfo
Exemplo n.º 19
0
def _match_stmt(ctx, stmt, spec, canonical):
    """Match stmt against the spec.

    Return None | spec'
    spec' is an updated spec with the matching spec consumed
    """
    i = 0
    while i < len(spec):
        (keywd, occurance) = spec[i]
        if keywd == '$any':
            return spec
        elif keywd == stmt.keyword:
            if occurance == '1' or occurance == '?':
                # consume this match
                if canonical == True:
                    return spec[i + 1:]
                else:
                    return spec[:i] + spec[i + 1:]
            if occurance == '+':
                # mark that we have found the one that was needed
                c = (keywd, '*')
                if canonical == True:
                    return [c] + spec[i + 1:]
                else:
                    return spec[:i] + [c] + spec[i + 1:]
            else:
                # occurane == '*'
                if canonical == True:
                    return spec[i:]
                else:
                    return spec
        elif keywd == '$choice':
            cases = occurance
            j = 0
            while j < len(cases):
                # check if this alternative matches - check for a
                # match with each optional keyword
                save_errors = ctx.errors
                match_res = _match_stmt(ctx, stmt, cases[j], canonical)
                if match_res != None:
                    # this case branch matched, use it
                    # remove the choice and add res to the spec
                    return spec[:i] + match_res + spec[i + 1:]
                # we must not report errors on non-matching branches
                ctx.errors = save_errors
                j += 1
        elif keywd == '$interleave':
            cspec = occurance
            match_res = _match_stmt(ctx, stmt, cspec, canonical)
            if match_res != None:
                # we got a match
                return spec
        elif util.is_prefixed(stmt.keyword):
            # allow extension statements mixed with these
            # set canonical to False in this call to just remove the
            # matching stmt from the spec
            match_res = _match_stmt(ctx, stmt, spec[i + 1:], False)
            if match_res != None:
                return spec[:i + 1] + match_res
            else:
                return None
        elif keywd == '$cut':
            # any non-optional statements left are errors
            for (keywd, occurance) in spec[:i]:
                if occurance == '1' or occurance == '+':
                    error.err_add(ctx.errors, stmt.pos, 'UNEXPECTED_KEYWORD_1',
                                  (util.keyword_to_str(stmt.raw_keyword),
                                   util.keyword_to_str(keywd)))
            # consume them so we don't report the same error again
            spec = spec[i:]
            i = 0
        elif canonical == True:
            if occurance == '1' or occurance == '+':
                error.err_add(ctx.errors, stmt.pos, 'UNEXPECTED_KEYWORD_1',
                              (util.keyword_to_str(stmt.raw_keyword),
                               util.keyword_to_str(keywd)))
                # consume it so we don't report the same error again
                spec = spec[i:]
                i = 0
        # check next in spec
        i += 1
    return None
def _match_stmt(ctx, stmt, spec, canonical):
    """Match stmt against the spec.

    Return None | spec'
    spec' is an updated spec with the matching spec consumed
    """
    i = 0
    while i < len(spec):
        (keywd, occurance) = spec[i]
        if keywd == '$any':
            return spec
        elif keywd == stmt.keyword:
            if occurance == '1' or occurance == '?':
                # consume this match
                if canonical == True:
                    return spec[i+1:]
                else:
                    return spec[:i] + spec[i+1:]
            if occurance == '+':
                # mark that we have found the one that was needed
                c = (keywd, '*')
                if canonical == True:
                    return [c] + spec[i+1:]
                else:
                    return spec[:i] + [c] + spec[i+1:]
            else:
                # occurane == '*'
                if canonical == True:
                    return spec[i:]
                else:
                    return spec
        elif keywd == '$choice':
            cases = occurance
            j = 0
            while j < len(cases):
                # check if this alternative matches - check for a
                # match with each optional keyword
                save_errors = ctx.errors
                match_res = _match_stmt(ctx, stmt, cases[j], False)
                if match_res != None:
                    # this case branch matched, use it
                    # remove the choice and add res to the spec
                    return spec[:i] + match_res + spec[i+1:]
                # we must not report errors on non-matching branches
                ctx.errors = save_errors
                j += 1
        elif keywd == '$interleave':
            cspec = occurance
            match_res = _match_stmt(ctx, stmt, cspec, canonical)
            if match_res != None:
                # we got a match
                return spec
        elif util.is_prefixed(stmt.keyword):
            # allow extension statements mixed with these
            # set canonical to False in this call to just remove the
            # matching stmt from the spec
            match_res = _match_stmt(ctx, stmt, spec[i+1:], False)
            if match_res != None:
                return spec[:i+1] + match_res
            else:
                return None
        elif keywd == '$cut':
            # any non-optional statements left are errors
            for (keywd, occurance) in spec[:i]:
                if occurance == '1' or occurance == '+':
                    error.err_add(ctx.errors, stmt.pos, 'UNEXPECTED_KEYWORD_1',
                                  (util.keyword_to_str(stmt.raw_keyword),
                                   util.keyword_to_str(keywd)))
            # consume them so we don't report the same error again
            spec = spec[i:]
            i = 0
        elif canonical == True:
            if occurance == '1' or occurance == '+':
                error.err_add(ctx.errors, stmt.pos, 'UNEXPECTED_KEYWORD_1',
                              (util.keyword_to_str(stmt.raw_keyword),
                               util.keyword_to_str(keywd)))
                # consume it so we don't report the same error again
                spec = spec[i:]
                i = 0
        # check next in spec
        i += 1
    return None
Exemplo n.º 21
0
def convert_stmt(ctx, stmt, level):
    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 == 'module':
        # Change the module name.
        module_name = stmt.arg
        stmt.arg = module_name + '-state'

        # Find the module prefix.
        prefix_stmt = next(x for x in stmt.substmts if x.keyword == 'prefix')

        # Rename the prefix statement.
        prefix = prefix_stmt.arg
        prefix_stmt.arg = prefix + '-s'

        # Add an import statement back to the original module.
        import_stmt = Statement(stmt.top, stmt, stmt.pos, 'import',
                                module_name)
        add_substmt_canonical(stmt, import_stmt)
        add_substmt_canonical(
            import_stmt,
            Statement(stmt.top, import_stmt, import_stmt.pos, 'prefix',
                      prefix))

    if keyword == 'submodule':
        # Change the module name.
        submodule_name = stmt.arg
        stmt.arg = submodule_name + '-state'

    if keyword == 'namespace':
        stmt.arg = stmt.arg + '-state'

    # Remove any feature statements, reference the original module feature instead.
    if keyword == 'feature':
        stmt.parent.substmts.remove(stmt)

    if keyword == 'if-feature':
        fix_references(stmt, stmt.i_module.i_features)

    # Remove any identity statements, reference the original identity instead.
    # Identity base won't matter because they are all removed.
    if keyword == 'identity':
        stmt.parent.substmts.remove(stmt)

    if keyword in ('include', 'belongs-to'):
        stmt.arg = stmt.arg + "-state"

    if keyword == "prefix" and stmt.parent.keyword == "belongs-to":
        stmt.arg = stmt.arg + "-s"

    # Remove must/when statements.
    if keyword in ('must', 'when'):
        stmt.parent.substmts.remove(stmt)
        #fix_references(stmt, stmt.i_module.i_identities)

    if keyword == 'type' and stmt.arg == 'identityref':
        base_stmt = next(x for x in stmt.substmts if x.keyword == 'base')
        fix_references(base_stmt, stmt.i_module.i_identities)

    # Remove any typedef statements, reference the original typedef instead.
    if keyword == 'typedef':
        stmt.parent.substmts.remove(stmt)

    if keyword == 'type':
        fix_references(stmt, stmt.i_module.i_typedefs)

    # Remove all config statements, only the top level config false is necessary.
    if keyword == 'config':
        stmt.parent.substmts.remove(stmt)

    if len(stmt.substmts) != 0:
        #substmts = grammar.sort_canonical(stmt.keyword, stmt.substmts)
        for s in stmt.substmts[:]:
            convert_stmt(ctx, s, level + 1)

    # Convert top level containers from "foo" to "foo-state", and mark it as config false.
    if keyword in ('container', 'list',
                   'leaf-list') and (stmt.parent.keyword == 'module'
                                     or stmt.parent.keyword == 'grouping'):
        if not stmt.arg.endswith('-state'):
            #stmt.arg = stmt.arg + '-state'
            add_substmt_canonical(
                stmt, Statement(stmt.top, stmt, stmt.pos, 'config', 'false'))
Exemplo n.º 22
0
def v_instantiate_extends(ctx, stmt):
    """Instantiate 'extends' statements, expand the complex type with
    the nodes from the base complex type. Applies refinements.
    """
    # the complex type is not grammatically valid
    if hasattr(stmt, 'is_grammatically_valid') and \
            not stmt.is_grammatically_valid:
        return
    # there is a circular dependency, don't process the 'extends' statement
    if stmt.i_is_circular:
        return
    bt = stmt.i_base_type
    # the complex type does not extend any other class
    if bt is None:
        return
    if hasattr(stmt, 'i_base_type_expanded'):
        return
    extends = stmt.search_one((ct_module_name, str_extends))
    v_instantiate_extends(ctx, bt)
    # copy the base complex type definitions into stmt.i_children
    names = {}
    for ch in bt.i_children:
        # don't copy the type since it cannot be modified anyway.
        if not (ch.i_module.i_modulename, ch.arg) in names:
            newnode = ch.copy(stmt, extends,
                      nocopy=['type','uses','unique','typedef','grouping'],
                      copyf=post_copy_fnc(extends, True))       
            stmt.i_children.append(newnode)
            newnode.i_is_inherited = True
            names[(ch.i_module.i_modulename, ch.arg)] = True
    stmt.i_base_type_expanded = True

    refined = {}
    # then apply all refinements

    for refinement in stmt.search('refine'):
        # process 'refine' statements
        target = find_target_node(ctx, refinement)
        if target is None:
            continue
        if target in refined:
            err_add(ctx.errors, refinement.pos, 'MULTIPLE_REFINE',
                (target.arg, refined[target]))
            continue
        if not hasattr(target, 'i_inherited'):
            err_add(ctx.errors, refinement.pos, 'REFINE_NOT_INHERITED',
                (target.arg, target.pos))
            continue
        refined[target] = refinement.pos

        def replace_from_refinement(target, refinement, keyword, \
            valid_keywords, v_fun=None, is_additional = False):

            """allow `keyword` as a refinement in `valid_keywords`"""
            new = refinement.search_one(keyword)
            if new is not None and target.keyword in valid_keywords:
                old = target.search_one(keyword)
                if old is not None and not is_additional:
                    target.substmts.remove(old)
                if v_fun is not None:
                    v_fun(target, new)
                target.substmts.append(new)
            elif new is not None:
                err_add(ctx.errors, refinement.pos, 'BAD_REFINEMENT',
                        (target.keyword, target.i_module.i_modulename,
                         target.arg, keyword))
                return

        def v_default(target, default):
            type = target.search_one('type')
            if (type is not None and type.i_type_spec is not None):
                defval = type.i_type_spec.str_to_val(ctx.errors,
                                                     default.pos,
                                                     default.arg)
                target.i_default = defval
                target.i_default_str = default.arg
                if defval is not None:
                    type.i_type_spec.validate(ctx.errors, default.pos, defval,
                        ' for the default value')

        replace_from_refinement(target, refinement, 'description',
            ['container', 'leaf', 'leaf-list', 'list', 'choice', 'case',
            'anyxml', (ct_module_name, str_instance),
            (ct_module_name, str_instance_list)])
        replace_from_refinement(target, refinement, 'reference',
            ['container', 'leaf', 'leaf-list', 'list',  'choice', 'case',
            'anyxml', (ct_module_name, str_instance),
            (ct_module_name, str_instance_list)])
        replace_from_refinement(target, refinement, 'config',
            ['container', 'leaf', 'leaf-list', 'list',  'choice', 'anyxml',
            (ct_module_name, str_instance),
            (ct_module_name, str_instance_list)])
        replace_from_refinement(target, refinement, 'presence', ['container'])
        replace_from_refinement(target, refinement, 'must',
            ['container', 'leaf', 'leaf-list', 'list',
            (ct_module_name, str_instance),
            (ct_module_name, str_instance_list)], is_additional = True)
        replace_from_refinement(target, refinement, 'default',
            ['leaf', 'choice'], v_default)
        replace_from_refinement(target, refinement, 'mandatory',
            ['leaf', 'choice', (ct_module_name, str_instance)])
        replace_from_refinement(target, refinement, 'min-elements',
            ['leaf-list', 'list', (ct_module_name, str_instance_list)])
        replace_from_refinement(target, refinement, 'max-elements',
            ['leaf-list', 'list', (ct_module_name, str_instance_list)])
        # replace all vendor-specific statements
        for s in refinement.substmts:
            if util.is_prefixed(s.keyword):
                old = target.search_one(s.keyword)
                if old is not None:
                    target.substmts.remove(old)
                target.substmts.append(s)
Exemplo n.º 23
0
 def is_appinfo(keyword):
     if util.is_prefixed(keyword) == True:
         return False
     (argname, argiselem, argappinfo) = yang_keywords[keyword]
     return argappinfo