blob: 57d4a3177ef852286ab96218f97bc1a9dd4112bd [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:
35 string = ''
36 for arg in args:
37 string += str(arg) + ' '
38 print string
39
40def leaftype(x):
41 return isinstance(x, str) or isinstance(x, unicode) or \
42 isinstance(x, type(1)) or isinstance(x, type(True))
43
44def substitute(templist, chains, db, depth):
45 depth += 1
46 log_print(Verbosity.info, "substitute(",templist, chains, db, depth,")")
47 if isinstance(db, type([])):
48 # db node is list
49 outlist = []
50 for instance in db:
51 log_print(Verbosity.info, "Going deeper at", depth, "for db list instance", instance)
52 outlist.extend(substitute(templist, chains, instance, depth))
53 log_print(Verbosity.info, "substitute", depth, "returning from list with", outlist)
54 return outlist
55
56 # db node is dict/leaf
57 transientlist = list(templist)
58 # find chain groups with same key
59 chaingroups = {"chains": [], "keys": []}
60 for chain in chains:
61 key = re.search('\w+', templist[chain])
62 if not key:
63 # chain does not define a leaf
64 print "chain", chain, "out of keys before reaching leaf"
65 continue
66 key = key.group(0) # convert MatchObj to string
67 for idx, groupkey in enumerate(chaingroups["keys"]):
68 if key == groupkey:
69 # insert chain in group
70 chaingroups["chains"][idx].append(chain)
71 break
72 else:
73 # key not yet in the list
74 chaingroups["keys"].append(key)
75 chaingroups["chains"].append([chain])
76
77 log_print(Verbosity.debug, chaingroups)
78
79 for groupidx, key in enumerate(chaingroups["keys"]):
80 log_print(Verbosity.info, "key lookup in", db, "for", key)
81 if key in db.keys():
82 if leaftype(db[key]):
83 # db node is leaf
84 for chain in chaingroups["chains"][groupidx]:
85 transientlist[chain] = str(db[key])
86 chaingroups["chains"][groupidx] = []
87 else:
88 # db node is branch
89 for chain in chaingroups["chains"][groupidx]:
90 transientlist[chain] = re.sub(REfirstkeyword, "@@", templist[chain])
91 else:
92 # key not found in database
93 if MISSING_KEYS_ACTION == 'report' or MISSING_KEYS_ACTION == 'halt':
94 print "key", key, "not found, invalid chains", chaingroups["chains"][groupidx]
95 placeholder = False
96 if MISSING_KEYS_ACTION == 'hide':
97 placeholder = ""
98 if 'replace' in MISSING_KEYS_ACTION:
99 placeholder = MISSING_KEYS_ACTION.replace("replace ", "")
100 for chain in chaingroups["chains"][groupidx]:
101 transientlist[chain] = placeholder
102 chaingroups["chains"][groupidx] = []
103 if MISSING_KEYS_ACTION == 'halt':
104 exit(1)
105 log_print(Verbosity.debug, "**** after selection chaingroups:", chaingroups, transientlist)
106 forked = False
107 for chidx, chains in enumerate(chaingroups["chains"]):
108 if chains:
109 key = chaingroups["keys"][chidx]
110 log_print(Verbosity.info, "Going deeper at", depth, "for chains", chains, "in dict", db[key])
111 if not forked:
112 outlist = substitute(transientlist, chains, db[key], depth)
113 forked = True
114 else:
115 transientlist = list(outlist)
116 outlist = list()
117 for item in transientlist:
118 outlist.extend(substitute(item, chains, db[key], depth))
119
120 if not forked:
121 outlist = [transientlist]
122
123 log_print(Verbosity.info, "substitute", depth, "returning from dict/leaf with", outlist)
124 return outlist
125
126def keyword_substitute(db, line, missing_keys):
127 global MISSING_KEYS_ACTION
128 chains = []
129 MISSING_KEYS_ACTION = missing_keys
130 log_print(Verbosity.info, line)
131 templist = re.split("(" + REkeychain + ")", line)
132 for idx, item in enumerate(templist):
133 if re.match(REkeychain, item):
134 chains.append(idx)
135 log_print(Verbosity.info, "Keychain:", item)
136 outlist = substitute(templist, chains, db, 0)
137 outstring = ""
138 for outline in outlist:
139 outstring += ''.join(outline) + "\n"
140 log_print(Verbosity.info, "generator returns with:")
141 log_print(Verbosity.info, outstring, "<<")
142 return outlist