From dc532704d082ecd3ff6a724cc9f2e5748c68179e Mon Sep 17 00:00:00 2001 From: Jan Lindemann Date: Sat, 4 Apr 2020 11:35:26 +0200 Subject: [PATCH] StringTree: Add support for adding StringTree children Add support for adding children of type StringTree. If a StringTree argument is passed to .add(), this should do the right thing. It makes use of the newly added .__add_children() method and involves quite a bit of hairy case distinctions. Signed-off-by: Jan Lindemann --- tools/python/jwutils/stree/StringTree.py | 54 +++++++++++++++++------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/tools/python/jwutils/stree/StringTree.py b/tools/python/jwutils/stree/StringTree.py index afb391d..94c239e 100644 --- a/tools/python/jwutils/stree/StringTree.py +++ b/tools/python/jwutils/stree/StringTree.py @@ -48,29 +48,51 @@ class StringTree: # export # regex ( content = regex, children = [ '[ \n\t\r]+' ] ) # '[ \n\t\r]+)' ( content = '\n\t\r]+)', children = [] ) + def __add_children(self, rhs): + assert isinstance(rhs, StringTree) + slog(DEBUG, "{}: adding children of {}: ".format(str(self), str(rhs)), str(rhs.children)) + #rhs.dump(INFO, "These children are added") + self.content = rhs.content + for name, c in rhs.children.items(): + if not name in self.children.keys(): + slog(DEBUG, "{}: adding new child: ".format(str(self), str(c))) + self.children[name] = c + else: + self.children[name].__add_children(c) + def __set(self, path_, content, split=True): - logcontent = "not-yet" - if hasattr(self, "content"): - logcontent = self.content - slog(DEBUG, "+ setting >" + str(content) + "< at path \"" + str(path_) + "\" to", logcontent) + slog(DEBUG, "+ setting >" + str(content) + "< at path \"" + str(path_) + "\"" + + (', containing "{}"'.format(str(self.content))) if hasattr(self, "content") else "") + assert self.content != str(content) + if content is not None and not type(content) in [str, StringTree]: + raise Exception("Tried to add content of unsupported type {}".format(type(content).__name__)) if path_ is None: - self.content = cleanup_string(content) + if isinstance(content, str): + self.content = cleanup_string(content) + elif isinstance(content, StringTree): + self.__add_children(content) + else: + raise Exception("Tried to add content of unsupported type {}".format(type(content).__name__)) slog(DEBUG, " -- content = >" + str(content) + "<, self.content = >" + str(self.content) + "<") return self path = cleanup_string(path_) components = path.split('.') if split else [ path ] l = len(components) if len(path) == 0 or l == 0: - assert self.content is None - #self.content = cleanup_string(content) - self.content = content - slog(DEBUG, " -- content = >" + str(content) + "<, self.content = >" + str(self.content) + "<") - #assert(content != "'antlr_doesnt_understand_vertical_tab'") - assert(content != '"[a-zA-Z0-9+_*/-]"') - #self.children[content] = StringTree(None, content) + #assert self.content is None or (isinstance(content, StringTree) and content.content == self.content) + if isinstance(content, StringTree): + #assert isinstance(content, StringTree), "Type: " + type(content).__name__ + self.__add_children(content) + else: + #self.content = cleanup_string(content) + self.content = content + slog(DEBUG, " -- content = >" + str(content) + "<, self.content = >" + str(self.content) + "<") + #assert(content != "'antlr_doesnt_understand_vertical_tab'") + assert(content != '"[a-zA-Z0-9+_*/-]"') + #self.children[content] = StringTree(None, content) return self - assert self.content is not None + #assert self.content is not None, "tried to set empty content to {}".format(path_) nibble = components[0] rest = '.'.join(components[1:]) @@ -80,7 +102,8 @@ class StringTree: # export assert len(rest) > 0 return self.children[nibble].__set(rest, content=content) if content is not None: - self.children[nibble].children[content] = StringTree('', content=content) + gc = content if isinstance(content, StringTree) else StringTree('', content=content) + self.children[nibble].children[gc.content] = gc return self.children[nibble] def __str__(self): @@ -121,7 +144,8 @@ class StringTree: # export return self.__set(path, content, split) def get(self, path_): - slog(DEBUG, "looking for", path_, "in", self.content) + slog(DEBUG, 'looking for "{}" in "{}"'.format(path_, self.content)) + assert not isinstance(path_, int) path = cleanup_string(path_) if len(path) == 0: slog(DEBUG, "returning myself")