build/plat: improve handling of get_override().
The existing functionality of get_override was poorly specified and ill-purposed for boolean flags. This change extracts the core variable retrieval logic to a helper function and adds a new handler `get_override_flag` which special cases boolean flags. The new behavior will also perform type checking on kwargs and inform the user of the desired type expected.
This commit is contained in:
parent
07c6ea5af2
commit
9eb208c332
|
@ -315,6 +315,50 @@ class TemplatedPlatform(Platform):
|
||||||
|
|
||||||
rtlil_text, self._name_map = rtlil.convert_fragment(fragment, name=name)
|
rtlil_text, self._name_map = rtlil.convert_fragment(fragment, name=name)
|
||||||
|
|
||||||
|
# Retrieve an override specified in either the environment or as a kwarg.
|
||||||
|
# expected_type parameter is used to assert the type of kwargs, passing `None` will disable
|
||||||
|
# type checking.
|
||||||
|
def _extract_override(var, *, expected_type):
|
||||||
|
deprecated_var_env = "NMIGEN_{}".format(var)
|
||||||
|
var_env = "AMARANTH_{}".format(var)
|
||||||
|
if deprecated_var_env in os.environ or var_env in os.environ:
|
||||||
|
# On Windows, there is no way to define an "empty but set" variable; it is tempting
|
||||||
|
# to use a quoted empty string, but it doesn't do what one would expect. Recognize
|
||||||
|
# this as a useful pattern anyway, and treat `set VAR=""` on Windows the same way
|
||||||
|
# `export VAR=` is treated on Linux.
|
||||||
|
if var_env in os.environ:
|
||||||
|
var_env_value = os.environ[var_env]
|
||||||
|
elif deprecated_var_env in os.environ:
|
||||||
|
var_env_value = os.environ[deprecated_var_env]
|
||||||
|
return re.sub(r'^\"\"$', "", var_env_value)
|
||||||
|
elif var in kwargs:
|
||||||
|
if not isinstance(kwargs[var], expected_type) and not expected_type is None:
|
||||||
|
raise TypeError("Override '{}' must be a {}, not {!r}".format(var, expected_type.__name__, kwargs[var]))
|
||||||
|
else:
|
||||||
|
return kwargs[var]
|
||||||
|
else:
|
||||||
|
return jinja2.Undefined(name=var)
|
||||||
|
|
||||||
|
def get_override(var):
|
||||||
|
value = _extract_override(var, expected_type=str)
|
||||||
|
return value
|
||||||
|
|
||||||
|
def get_override_flag(var):
|
||||||
|
value = _extract_override(var, expected_type=bool)
|
||||||
|
if isinstance(value, str):
|
||||||
|
value = value.lower()
|
||||||
|
if value in ("0", "no", "n", "false", ""):
|
||||||
|
return False
|
||||||
|
if value in ("1", "yes", "y", "true"):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
raise ValueError("Override '{}' must be one of "
|
||||||
|
"(\"0\", \"n\", \"no\", \"false\", \"\") "
|
||||||
|
"or "
|
||||||
|
"(\"1\", \"y\", \"yes\", \"true\"), not {!r}"
|
||||||
|
.format(var, value))
|
||||||
|
return value
|
||||||
|
|
||||||
def emit_rtlil():
|
def emit_rtlil():
|
||||||
return rtlil_text
|
return rtlil_text
|
||||||
|
|
||||||
|
@ -354,27 +398,6 @@ class TemplatedPlatform(Platform):
|
||||||
|
|
||||||
return "\n".join(commands)
|
return "\n".join(commands)
|
||||||
|
|
||||||
def get_override(var):
|
|
||||||
deprecated_var_env = "NMIGEN_{}".format(var)
|
|
||||||
var_env = "AMARANTH_{}".format(var)
|
|
||||||
if deprecated_var_env in os.environ or var_env in os.environ:
|
|
||||||
# On Windows, there is no way to define an "empty but set" variable; it is tempting
|
|
||||||
# to use a quoted empty string, but it doesn't do what one would expect. Recognize
|
|
||||||
# this as a useful pattern anyway, and treat `set VAR=""` on Windows the same way
|
|
||||||
# `export VAR=` is treated on Linux.
|
|
||||||
if var_env in os.environ:
|
|
||||||
var_env_value = os.environ[var_env]
|
|
||||||
elif deprecated_var_env in os.environ:
|
|
||||||
var_env_value = os.environ[deprecated_var_env]
|
|
||||||
return re.sub(r'^\"\"$', "", var_env_value)
|
|
||||||
elif var in kwargs:
|
|
||||||
if isinstance(kwargs[var], str):
|
|
||||||
return textwrap.dedent(kwargs[var]).strip()
|
|
||||||
else:
|
|
||||||
return kwargs[var]
|
|
||||||
else:
|
|
||||||
return jinja2.Undefined(name=var)
|
|
||||||
|
|
||||||
@jinja2.pass_context
|
@jinja2.pass_context
|
||||||
def invoke_tool(context, name):
|
def invoke_tool(context, name):
|
||||||
env_var = tool_env_var(name)
|
env_var = tool_env_var(name)
|
||||||
|
@ -409,13 +432,13 @@ class TemplatedPlatform(Platform):
|
||||||
return '"' + re.sub(r"([$[\\])", r"\\\1", string) + '"'
|
return '"' + re.sub(r"([$[\\])", r"\\\1", string) + '"'
|
||||||
|
|
||||||
def verbose(arg):
|
def verbose(arg):
|
||||||
if get_override("verbose"):
|
if get_override_flag("verbose"):
|
||||||
return arg
|
return arg
|
||||||
else:
|
else:
|
||||||
return jinja2.Undefined(name="quiet")
|
return jinja2.Undefined(name="quiet")
|
||||||
|
|
||||||
def quiet(arg):
|
def quiet(arg):
|
||||||
if get_override("verbose"):
|
if get_override_flag("verbose"):
|
||||||
return jinja2.Undefined(name="quiet")
|
return jinja2.Undefined(name="quiet")
|
||||||
else:
|
else:
|
||||||
return arg
|
return arg
|
||||||
|
@ -443,6 +466,7 @@ class TemplatedPlatform(Platform):
|
||||||
"syntax": syntax,
|
"syntax": syntax,
|
||||||
"invoke_tool": invoke_tool,
|
"invoke_tool": invoke_tool,
|
||||||
"get_override": get_override,
|
"get_override": get_override,
|
||||||
|
"get_override_flag": get_override_flag,
|
||||||
"verbose": verbose,
|
"verbose": verbose,
|
||||||
"quiet": quiet,
|
"quiet": quiet,
|
||||||
"autogenerated": autogenerated,
|
"autogenerated": autogenerated,
|
||||||
|
|
Loading…
Reference in a new issue