blob: 9a98aae5e310e208a0083af598bfc7adcd55aeac [file] [log] [blame]
Miklos Balint470919c2018-05-22 17:51:29 +02001#-------------------------------------------------------------------------------
2# Copyright (c) 2018, Arm Limited. All rights reserved.
3#
4# SPDX-License-Identifier: BSD-3-Clause
5#
6#-------------------------------------------------------------------------------
7
8import re
9try:
10 from enum import Enum
11except ImportError as e:
12 print e, "To install it, type:"
13 print "pip install enum34"
14 exit(1)
15
16class Verbosity(Enum):
17 debug = 3
18 info = 2
19 warning = 1
20 error = 0
21
22# Set default value
23VERBOSITY = Verbosity.info
24
25REkeychain = "@@\w+[\.\w+]*@@"
26REfirstkeyword = "@@\w+\.?"
27
28MISSING_KEYS_ACTION = 'halt'
29
30def log_print(level, *args, **kwargs):
31 global VERBOSITY
32 if kwargs.get("verbosity"):
33 VERBOSITY = kwargs["verbosity"]
34 if level.value <= VERBOSITY.value:
Miklos Balint3a05c9d2018-05-31 09:31:27 +020035 string = ' '.join(map(str, args))
Miklos Balint470919c2018-05-22 17:51:29 +020036 print string
37
38def leaftype(x):
39 return isinstance(x, str) or isinstance(x, unicode) or \
40 isinstance(x, type(1)) or isinstance(x, type(True))
41
42def substitute(templist, chains, db, depth):
43 depth += 1
44 log_print(Verbosity.info, "substitute(",templist, chains, db, depth,")")
45 if isinstance(db, type([])):
46 # db node is list
47 outlist = []
48 for instance in db:
49 log_print(Verbosity.info, "Going deeper at", depth, "for db list instance", instance)
50 outlist.extend(substitute(templist, chains, instance, depth))
51 log_print(Verbosity.info, "substitute", depth, "returning from list with", outlist)
52 return outlist
53
54 # db node is dict/leaf
55 transientlist = list(templist)
56 # find chain groups with same key
57 chaingroups = {"chains": [], "keys": []}
58 for chain in chains:
59 key = re.search('\w+', templist[chain])
60 if not key:
61 # chain does not define a leaf
62 print "chain", chain, "out of keys before reaching leaf"
63 continue
64 key = key.group(0) # convert MatchObj to string
65 for idx, groupkey in enumerate(chaingroups["keys"]):
66 if key == groupkey:
67 # insert chain in group
68 chaingroups["chains"][idx].append(chain)
69 break
70 else:
71 # key not yet in the list
72 chaingroups["keys"].append(key)
73 chaingroups["chains"].append([chain])
74
75 log_print(Verbosity.debug, chaingroups)
76
77 for groupidx, key in enumerate(chaingroups["keys"]):
78 log_print(Verbosity.info, "key lookup in", db, "for", key)
79 if key in db.keys():
80 if leaftype(db[key]):
81 # db node is leaf
82 for chain in chaingroups["chains"][groupidx]:
83 transientlist[chain] = str(db[key])
84 chaingroups["chains"][groupidx] = []
85 else:
86 # db node is branch
87 for chain in chaingroups["chains"][groupidx]:
88 transientlist[chain] = re.sub(REfirstkeyword, "@@", templist[chain])
89 else:
90 # key not found in database
91 if MISSING_KEYS_ACTION == 'report' or MISSING_KEYS_ACTION == 'halt':
92 print "key", key, "not found, invalid chains", chaingroups["chains"][groupidx]
93 placeholder = False
94 if MISSING_KEYS_ACTION == 'hide':
95 placeholder = ""
96 if 'replace' in MISSING_KEYS_ACTION:
97 placeholder = MISSING_KEYS_ACTION.replace("replace ", "")
98 for chain in chaingroups["chains"][groupidx]:
99 transientlist[chain] = placeholder
100 chaingroups["chains"][groupidx] = []
101 if MISSING_KEYS_ACTION == 'halt':
102 exit(1)
103 log_print(Verbosity.debug, "**** after selection chaingroups:", chaingroups, transientlist)
104 forked = False
105 for chidx, chains in enumerate(chaingroups["chains"]):
106 if chains:
107 key = chaingroups["keys"][chidx]
108 log_print(Verbosity.info, "Going deeper at", depth, "for chains", chains, "in dict", db[key])
109 if not forked:
110 outlist = substitute(transientlist, chains, db[key], depth)
111 forked = True
112 else:
113 transientlist = list(outlist)
114 outlist = list()
115 for item in transientlist:
116 outlist.extend(substitute(item, chains, db[key], depth))
117
118 if not forked:
119 outlist = [transientlist]
120
121 log_print(Verbosity.info, "substitute", depth, "returning from dict/leaf with", outlist)
122 return outlist
123
124def keyword_substitute(db, line, missing_keys):
125 global MISSING_KEYS_ACTION
126 chains = []
127 MISSING_KEYS_ACTION = missing_keys
128 log_print(Verbosity.info, line)
129 templist = re.split("(" + REkeychain + ")", line)
130 for idx, item in enumerate(templist):
131 if re.match(REkeychain, item):
132 chains.append(idx)
133 log_print(Verbosity.info, "Keychain:", item)
134 outlist = substitute(templist, chains, db, 0)
135 outstring = ""
136 for outline in outlist:
137 outstring += ''.join(outline) + "\n"
138 log_print(Verbosity.info, "generator returns with:")
Miklos Balint3a05c9d2018-05-31 09:31:27 +0200139 log_print(Verbosity.info, outstring + "<<")
Miklos Balint470919c2018-05-22 17:51:29 +0200140 return outlist