plat, vendor: systematically escape net and file names in Tcl.

Before this commit, there was only occasional quoting of some names
used in any Tcl files. (I'm not sure what I was thinking.)

After this commit, any substs that may include Tcl special characters
are escaped. This does not include build names (which are explicitly
restricted to ASCII to avoid this problem), or attribute names (which
are chosen from a predefined set). Ideally we'd use a more principled
approach but Jinja2 does not support custom escaping mechanisms.

Note that Vivado restricts clock names to a more restrictive set that
forbids using Tcl special characters even when escaped.

Fixes #375.
This commit is contained in:
whitequark 2020-05-02 10:41:18 +00:00
parent 6e29fbcc61
commit 6cee280407
7 changed files with 50 additions and 37 deletions

View file

@ -368,6 +368,17 @@ class TemplatedPlatform(Platform):
def hierarchy(signal, separator):
return separator.join(name_map[signal][1:])
def ascii_escape(string):
def escape_one(match):
if match.group(1) is None:
return match.group(2)
else:
return "_{:02x}_".format(ord(match.group(1)[0]))
return "".join(escape_one(m) for m in re.finditer(r"([^A-Za-z0-9_])|(.)", string))
def tcl_escape(string):
return "{" + re.sub(r"([{}\\])", r"\\\1", string) + "}"
def verbose(arg):
if "NMIGEN_verbose" in os.environ:
return arg
@ -387,6 +398,8 @@ class TemplatedPlatform(Platform):
trim_blocks=True, lstrip_blocks=True, undefined=jinja2.StrictUndefined)
compiled.environment.filters["options"] = options
compiled.environment.filters["hierarchy"] = hierarchy
compiled.environment.filters["ascii_escape"] = ascii_escape
compiled.environment.filters["tcl_escape"] = tcl_escape
except jinja2.TemplateSyntaxError as e:
e.args = ("{} (at {}:{})".format(e.message, origin, e.lineno),)
raise