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'))
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)
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')
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')
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)
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')
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)
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')
def add_substmt_canonical(parent_stmt, stmt): parent_stmt.substmts.append(stmt) parent_stmt.substmts = grammar.sort_canonical(parent_stmt.keyword, parent_stmt.substmts)
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)