def chk_key(old, new, ctx): oldkey = old.search_one('key') newkey = new.search_one('key') if oldkey is None and newkey is None: pass elif oldkey is None and newkey is not None: err_def_added(newkey, ctx) elif oldkey is not None and newkey is None: err_def_removed(oldkey, new, ctx) else: # check the key argument string; i_key is not set in groupings oldks = [k for k in oldkey.arg.split() if k != ''] newks = [k for k in newkey.arg.split() if k != ''] if len(oldks) != len(newks): err_def_changed(oldkey, newkey, ctx) else: for ok, nk in zip(oldks, newks): if util.split_identifier(ok)[1] != util.split_identifier(nk)[1]: err_def_changed(oldkey, newkey, ctx) return
def print_children(i_children, module, fd, prefix, path, ctx, level=0, exdata=None): global depth if len(i_children) > 0: depth = max(depth, level) for ch in i_children: disabled_feature = False iffeature = ch.search('if-feature') for f in iffeature: # find a feature in imported module [by robot] if ":" in f.arg: import_prefix, import_feature = util.split_identifier(f.arg) if import_prefix is not None and import_feature is not None: import_pos = None import_err = [] import_module = util.prefix_to_module( module, import_prefix, import_pos, import_err) if import_module is not None: if import_module in ctx.features and import_feature not in ctx.features[ import_module.arg]: print(ch.search("feature"), ch.search('if-feature'), ctx.features[module.arg], "disabled feature") # ignore disabled feature disabled_feature = True else: if f.arg not in ctx.features[module.arg]: print(ch.search("feature"), ch.search('if-feature'), ctx.features[module.arg], "disabled feature") # ignore disabled feature disabled_feature = True # if f.arg not in ctx.features[module.arg]: # print (ch.search("feature"), ch.search('if-feature'), ctx.features[module.arg], "disabled feature") # # ignore disabled feature # disabled_feature = True if not disabled_feature: print_node(ch, module, fd, prefix, path, ctx, level, exdata=exdata)
def typestring(node): def get_nontypedefstring(node): s = "" found = False t = node.search_one('type') if t is not None: s = t.arg + '\n' if t.arg == 'enumeration': found = True s = s + ' : {' for enums in t.substmts: s = s + enums.arg + ',' s = s + '}' elif t.arg == 'leafref': found = True s = s + ' : ' p = t.search_one('path') if p is not None: s = s + p.arg elif t.arg == 'identityref': found = True b = t.search_one('base') if b is not None: s = s + ' {' + b.arg + '}' elif t.arg == 'union': found = True uniontypes = t.search('type') s = s + '{' + uniontypes[0].arg for uniontype in uniontypes[1:]: s = s + ', ' + uniontype.arg s = s + '}' typerange = t.search_one('range') if typerange is not None: found = True s = s + ' [' + typerange.arg + ']' length = t.search_one('length') if length is not None: found = True s = s + ' {length = ' + length.arg + '}' pattern = t.search_one('pattern') if pattern is not None: # truncate long patterns found = True s = s + ' {pattern = ' + pattern.arg + '}' return s s = get_nontypedefstring(node) if s != "": t = node.search_one('type') # chase typedef type_namespace = None i_type_name = None prefix, name = util.split_identifier(t.arg) if prefix is None or t.i_module.i_prefix == prefix: # check local typedefs pmodule = node.i_module typedef = statements.search_typedef(t, name) else: # this is a prefixed name, check the imported modules err = [] pmodule = util.prefix_to_module(t.i_module, prefix, t.pos, err) if pmodule is None: return typedef = statements.search_typedef(pmodule, name) if typedef is not None: s = s + get_nontypedefstring(typedef) return s
def get_typename(s, prefix_with_modname=False): t = s.search_one('type') if t is not None: if t.arg == 'leafref': p = t.search_one('path') if p is not None: # Try to make the path as compact as possible. # Remove local prefixes, and only use prefix when # there is a module change in the path. target = [] curprefix = s.i_module.i_prefix for name in p.arg.split('/'): prefix, name = util.split_identifier(name) if prefix is None or prefix == curprefix: target.append(name) else: if prefix_with_modname: if prefix in s.i_module.i_prefixes: # Try to map the prefix to the module name module_name, _ = s.i_module.i_prefixes[prefix] else: # If we can't then fall back to the prefix module_name = prefix target.append(module_name + ':' + name) else: target.append(prefix + ':' + name) curprefix = prefix return "-> %s" % "/".join(target) else: # This should never be reached. Path MUST be present for # leafref type. See RFC6020 section 9.9.2 # (https://tools.ietf.org/html/rfc6020#section-9.9.2) if prefix_with_modname: prefix, name = util.split_identifier(t.arg) if prefix is None: # No prefix specified. Leave as is return t.arg else: # Prefix found. Replace it with the module name if prefix in s.i_module.i_prefixes: # Try to map the prefix to the module name module_name, _ = s.i_module.i_prefixes[prefix] else: # If we can't then fall back to the prefix module_name = prefix return module_name + ':' + name else: return t.arg else: if prefix_with_modname: prefix, name = util.split_identifier(t.arg) if prefix is None: # No prefix specified. Leave as is return t.arg else: # Prefix found. Replace it with the module name if prefix in s.i_module.i_prefixes: # Try to map the prefix to the module name module_name, _ = s.i_module.i_prefixes[prefix] else: # If we can't then fall back to the prefix module_name = prefix return module_name + ':' + name else: return t.arg elif s.keyword == 'anydata': return '<anydata>' elif s.keyword == 'anyxml': return '<anyxml>' else: return ''
def typestring(self, node): t = node.search_one('type') s = t.arg if t.arg == 'enumeration': s = s + ' : {' for enums in t.substmts[:3]: s = s + enums.arg + ',' if len(t.substmts) > 3: s = s + "..." s = s + '}' elif t.arg == 'leafref': # sys.stderr.write('in leafref \n') s = s + ' : ' p = t.search_one('path') if p is not None: # inthismodule, n = self.find_target_node(p) leafrefkey = p.arg leafrefkey = leafrefkey[leafrefkey.rfind("/") + 1:] leafrefparent = p.arg leafrefparent = leafrefparent[0:(leafrefparent.rfind("/"))] # shorten leafref attribute stuff here.... if self.ctx_truncate_leafrefs: s = s + '...' + leafrefkey else: s = s + p.arg # leafrefs might contain functions like current and deref wich makes PlantUML turn it into # methods. Replace () with {} s = s.replace('(', '{') s = s.replace(')', '}') if node.i_leafref_ptr is not None: n = node.i_leafref_ptr[0] else: n = None prefix, _ = util.split_identifier(p.arg) # FIXME: previous code skipped first char, possibly in error prefix = self.thismod_prefix if prefix is None else prefix[1:] if n is not None: if node.keyword == 'typedef': self.leafrefs.append( self.make_plantuml_keyword(node.arg) + '-->' + '"' + leafrefkey + '"' + self.full_path(n.parent) + ': ' + node.arg + '\n') else: self.leafrefs.append( self.full_path(node.parent) + '-->' + '"' + leafrefkey + '"' + self.full_path(n.parent) + ': ' + node.arg + '\n') if prefix not in self.module_prefixes: self.post_strings.append( 'class \"%s\" as %s <<leafref>> \n' % (leafrefparent, self.full_path(n.parent))) # self.post_strings.append('%s : %s\n' %(self.full_path(n.parent), leafrefkey)) sys.stderr.write( "Info: Leafref %s outside diagram. Prefix = %s\n" % (p.arg, prefix)) else: sys.stderr.write("Info: Did not find leafref target %s\n" % p.arg) #if n is not None and (inthismodule): # sys.stderr.write('leafref %s : target %s \n' %(p.arg, full_path(n))) # sys.stderr.write('in this module %s : \n' %inthismodule) # self.leafrefs.append(self.full_path(node.parent) + '-->' + '"' + leafrefkey + '"' + self.full_path(n.parent) + ': ' + node.arg + '\n') #elif n is not None and not inthismodule: # sys.stderr.write('in this module %s : \n' %inthismodule) # self.leafrefs.append('class \"%s\" as %s <<(L, Red)>>\n' %(leafrefparent, self.full_path(n.parent))) # self.leafrefs.append('%s : %s\n' %(self.full_path(n.parent), leafrefkey)) # self.leafrefs.append(self.full_path(node.parent) + '-->' + '"' + leafrefkey + '"' + self.full_path(n.parent) + ': ' + node.arg + '\n') elif t.arg == 'identityref': b = t.search_one('base') if b is not None: s = s + ' {' + b.arg + '}' if self.ctx_identityrefs and self.ctx_identities: self.post_strings.append( self.full_path(node.parent) + '-->' + self.make_plantuml_keyword(b.arg) + ': ' + node.arg + '\n') elif t.arg == 'union': uniontypes = t.search('type') s = s + '{' + uniontypes[0].arg for uniontype in uniontypes[1:2]: s = s + ', ' + uniontype.arg if len(uniontypes) > 3: s = s + ',..}' else: s = s + '}' typerange = t.search_one('range') if typerange is not None: s = s + ' [' + typerange.arg + ']' length = t.search_one('length') if length is not None: s = s + ' {length = ' + length.arg + '}' pattern = t.search_one('pattern') if pattern is not None: # truncate long patterns s = s + ' {pattern = ' + pattern.arg[:20] if len(pattern.arg) < 20: s = s + '}' else: s = s + '...}' return s
def emit_stmt(self, mod, stmt, fd): # find good UML roots if stmt.keyword == 'container': self.emit_container(mod, stmt, fd) for s in stmt.substmts: self.emit_child_stmt(stmt, s, fd) elif stmt.keyword == 'augment' and not self.ctx_filterfile: # HERE a = stmt.arg if self.ctx_truncate_augments: a = '...' + a[a.rfind('/'):] if not self.ctx_inline_augments: fd.write('class \"%s\" as %s << (A,CadetBlue) augment>>\n' % (a, self.full_path(stmt))) # ugly, the augmented elemented is suffixed with _ in emit_header # fd.write('_%s <-- %s : augment \n' %(self.full_path(stmt), self.full_path(stmt))) # also, since we are the root, add the module as parent if self.full_path( stmt ) not in self.augmentpaths and not self.ctx_inline_augments: fd.write('%s *-- %s \n' % (self.full_path(mod), self.full_path(stmt))) self.augmentpaths.append(self.full_path(stmt)) # MEF prefix, _ = util.split_identifier(stmt.arg) # FIXME: previous code skipped first char, possibly in error prefix = self.thismod_prefix if prefix is None else prefix[1:] node = statements.find_target_node(self._ctx, stmt, True) if node is not None and prefix in self.module_prefixes and not self.ctx_inline_augments: # sys.stderr.write("Found augment target : %s , %s \n" %(stmt.arg, self.full_path(node))) self.augments.append( self.full_path(stmt) + '-->' + self.full_path(node) + ' : augments' + '\n') else: # sys.stderr.write("Not Found augment target : %s \n" %(stmt.arg)) pass if self.ctx_inline_augments and node is not None: # Emit augment target, in case that module was given as input this results in duplicate, but plantUML do not care # The False flag stops emit_child from continuing iterating further down the tree self.emit_child_stmt(node.parent, node, fd, False) for s in stmt.substmts: s.parent = node self.emit_child_stmt(node, s, fd) else: for s in stmt.substmts: self.emit_child_stmt(stmt, s, fd) elif stmt.keyword == 'list': self.emit_list(mod, stmt, fd) for s in stmt.substmts: self.emit_child_stmt(stmt, s, fd) elif stmt.keyword == 'grouping' and not self._ctx.opts.uml_inline: self.emit_grouping(mod, stmt, fd, True) elif stmt.keyword == 'choice': if not self.ctx_filterfile: fd.write('class \"%s\" as %s <<choice>> \n' % (self.full_display_path(stmt), self.full_path(stmt))) fd.write('%s .. %s : choice \n' % (self.full_path(mod), self.full_path(stmt))) # sys.stderr.write('in choice %s \n', self.full_path(mod)) for children in stmt.substmts: self.emit_child_stmt(stmt, children, fd) elif stmt.keyword == 'case': if not self.ctx_filterfile: fd.write('class \"%s\" as %s \n' % (self.full_display_path(stmt), self.full_path(stmt))) fd.write('%s .. %s : choice\n' % (self.full_path(mod), self.full_path(stmt))) # sys.stderr.write('in case %s \n', full_path(mod)) for children in mod.substmts: self.emit_child_stmt(stmt, children, fd) elif stmt.keyword == 'identity': self.emit_identity(mod, stmt, fd) if not self.ctx_classesonly and not self.ctx_filterfile: if stmt.keyword == 'typedef': self.emit_typedef(mod, stmt, fd) elif stmt.keyword == 'rpc': self.emit_action(mod, stmt, fd) elif stmt.keyword == 'notification': self.emit_notif(mod, stmt, fd) elif stmt.keyword == 'feature': self.emit_feature(mod, stmt, fd) elif stmt.keyword == 'deviation': self.emit_feature(mod, stmt, fd)