+
+
+# TODO: make this a util routine (somewhere)
+def mask_extend(x, nbits, repeat):
+ res = 0
+ extended = (1 << repeat)-1
+ for i in range(nbits):
+ if x & (1 << i):
+ res |= extended << (i*repeat)
+ return res
+
+
+# makes a logarithmically-skewed random number
+def log_rand(n, min_val=1):
+ logrange = random.randint(1, n)
+ return random.randint(min_val, (1 << logrange)-1)
+
+
+class LogType(Enum):
+ Default = "default"
+ InstrInOuts = "instr_in_outs"
+ SkipCase = "skip_case"
+ OutputMatching = "output_matching"
+
+
+@lru_cache(typed=True)
+def __parse_log_env_var(silencelog_raw):
+ if silencelog_raw is None:
+ return {k: False for k in LogType}
+ silencelog = os.environ.decodevalue(silencelog_raw)
+ silencelog = silencelog.lower().split(",")
+ for i, v in enumerate(silencelog):
+ silencelog[i] = v.strip()
+ retval = {k: True for k in LogType}
+ if len(silencelog) > 1 and silencelog[-1] == "":
+ # allow trailing comma
+ silencelog.pop()
+ if len(silencelog) == 1:
+ if silencelog[0] in ("0", "false"):
+ for k in LogType:
+ retval[k] = False
+ silencelog.pop()
+ if silencelog[0] in ("1", "true", ""):
+ silencelog.pop()
+ for v in silencelog:
+ silenced = True
+ if v.startswith("!"):
+ v = v[1:]
+ silenced = False
+ matches = False
+ for k in LogType:
+ if fnmatchcase(k.value, v):
+ matches = True
+ retval[k] = silenced
+ assert matches, (f"SILENCELOG: {v!r} did not match any known LogType: "
+ f"LogTypes: {' '.join(i.value for i in LogType)}")
+ # for k, v in retval.items():
+ # print(repr(k), "silenced" if v else "active")
+ return retval
+
+
+__ENCODED_SILENCELOG = os.environ.encodekey("SILENCELOG")
+
+
+def log(*args, kind=LogType.Default, **kwargs):
+ """verbose printing, can be disabled by setting env var "SILENCELOG".
+ """
+ # look up in os.environ._data since it is a dict and hence won't raise
+ # internal exceptions to avoid triggering breakpoints on raised exceptions.
+ env_var = os.environ._data.get(__ENCODED_SILENCELOG, None)
+ silenced = __parse_log_env_var(env_var)
+ if silenced[kind]:
+ return
+ print(*args, **kwargs)