blob: 16873383ad87bf829afb2cf91d1e6255eb9d8aaa [file] [log] [blame]
#-------------------------------------------------------------------------------
# Copyright (c) 2018, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
#-------------------------------------------------------------------------------
import re
try:
from enum import Enum
except ImportError as e:
print e, "To install it, type:"
print "pip install enum34"
exit(1)
class Verbosity(Enum):
debug = 3
info = 2
warning = 1
error = 0
# Set default value
VERBOSITY = Verbosity.info
REkeychain = "@@\w+[\.\w+]*@@"
REfirstkeyword = "@@\w+\.?"
emptychain = "@@@@"
MISSING_KEYS_ACTION = 'halt'
def log_print(level, *args, **kwargs):
global VERBOSITY
if kwargs.get("verbosity"):
VERBOSITY = kwargs["verbosity"]
if level.value <= VERBOSITY.value:
string = ' '.join(map(str, args))
print string
def leaftype(x):
return isinstance(x, str) or isinstance(x, unicode) or \
isinstance(x, type(1)) or isinstance(x, type(True))
def substitute(templist, chains, db, depth):
depth += 1
log_print(Verbosity.info, "substitute(",templist, chains, db, depth,")")
if isinstance(db, type([])):
# db is list
outlist = []
for instance in db:
log_print(Verbosity.info, "Going deeper at", depth, "for db list instance", instance)
outlist.extend(substitute(templist, chains, instance, depth))
log_print(Verbosity.info, "substitute", depth, "returning from list with", outlist)
return outlist
transientlist = list(templist)
if leaftype(db):
# db is leaf
for chain in chains:
if templist[chain] == emptychain:
transientlist[chain] = str(db)
else:
print "keychain not empty but db is"
transientlist[chain] = str(db) + templist[chain]
continue
chains = []
log_print(Verbosity.info, "substitute", depth, "returning from leaf with", transientlist)
return transientlist
# db is dict
# find chain groups with same key
chaingroups = {"chains": [], "keys": []}
for chain in chains:
key = re.search('\w+', templist[chain])
if not key:
# chain does not define a leaf
print "chain", chain, "out of keys before reaching leaf"
continue
key = key.group(0) # convert MatchObj to string
for idx, groupkey in enumerate(chaingroups["keys"]):
if key == groupkey:
# insert chain in group
chaingroups["chains"][idx].append(chain)
break
else:
# key not yet in the list
chaingroups["keys"].append(key)
chaingroups["chains"].append([chain])
log_print(Verbosity.debug, chaingroups)
for groupidx, key in enumerate(chaingroups["keys"]):
log_print(Verbosity.info, "key lookup in", db, "for", key)
if key in db.keys():
if leaftype(db[key]):
# db entry value is leaf
for chain in chaingroups["chains"][groupidx]:
transientlist[chain] = str(db[key])
chaingroups["chains"][groupidx] = []
else:
# db node is branch
for chain in chaingroups["chains"][groupidx]:
transientlist[chain] = re.sub(REfirstkeyword, "@@", templist[chain])
else:
# key not found in database
if MISSING_KEYS_ACTION == 'report' or MISSING_KEYS_ACTION == 'halt':
print "key", key, "not found, invalid chains", chaingroups["chains"][groupidx]
placeholder = False
if MISSING_KEYS_ACTION == 'hide':
placeholder = ""
if 'replace' in MISSING_KEYS_ACTION:
placeholder = MISSING_KEYS_ACTION.replace("replace ", "")
for chain in chaingroups["chains"][groupidx]:
transientlist[chain] = placeholder
chaingroups["chains"][groupidx] = []
if MISSING_KEYS_ACTION == 'halt':
exit(1)
log_print(Verbosity.debug, "**** after selection chaingroups:", chaingroups, transientlist)
forked = False
for chidx, chains in enumerate(chaingroups["chains"]):
if chains:
key = chaingroups["keys"][chidx]
log_print(Verbosity.info, "Going deeper at", depth, "for chains", chains, "in dict", db[key])
if not forked:
outlist = substitute(transientlist, chains, db[key], depth)
forked = True
else:
transientlist = list(outlist)
outlist = list()
for item in transientlist:
outlist.extend(substitute(item, chains, db[key], depth))
if not forked:
outlist = [transientlist]
log_print(Verbosity.info, "substitute", depth, "returning from dict/leaf with", outlist)
return outlist
def keyword_substitute(db, line, missing_keys):
global MISSING_KEYS_ACTION
chains = []
MISSING_KEYS_ACTION = missing_keys
log_print(Verbosity.info, line)
templist = re.split("(" + REkeychain + ")", line)
for idx, item in enumerate(templist):
if re.match(REkeychain, item):
chains.append(idx)
log_print(Verbosity.info, "Keychain:", item)
outlist = substitute(templist, chains, db, 0)
outstring = ""
for outline in outlist:
outstring += ''.join(outline) + "\n"
log_print(Verbosity.info, "generator returns with:")
log_print(Verbosity.info, outstring + "<<")
return outlist