def getCondEval(self, runt): name = self.kids[0].value() # Allow for a user to ask for #* to signify "any tags on this node" if name == '*': async def cond(node, path): # Check if the tags dictionary has any members if node.tags: return True return False return cond # Allow a user to use tag globbing to do regex matching of a node. if '*' in name: reobj = s_cache.getTagGlobRegx(name) def getIsHit(tag): return reobj.fullmatch(tag) # This cache persists per-query cache = s_cache.FixedCache(getIsHit) async def cond(node, path): return any((cache.get(p) for p in node.tags)) return cond # Default exact match async def cond(node, path): return node.tags.get(name) is not None return cond
async def _methNodeGlobTags(self, glob): tags = list(self.valu.tags.keys()) regx = s_cache.getTagGlobRegx(glob) ret = [] for tag in tags: match = regx.fullmatch(tag) if match is not None: groups = match.groups() # Per discussion: The simple use case of a single match is # intuitive for a user to simply loop over as a raw list. # In contrast, a glob match which yields multiple matching # values would have to be unpacked. if len(groups) == 1: ret.append(groups[0]) else: ret.append(groups) return ret
async def _methNodeTags(self, glob=None): tags = list(self.valu.tags.keys()) if glob is not None: regx = s_cache.getTagGlobRegx(glob) tags = [t for t in tags if regx.fullmatch(t)] return tags
async def _methNodeTags(self, glob=None): tags = list(self.valu.tags.keys()) if glob is not None: regx = s_cache.getTagGlobRegx(glob) tags = [t for t in tags if regx.fullmatch(t)] return tags