Skip to content

Commit

Permalink
Merge pull request #1 from epics-containers/auto-normalize
Browse files Browse the repository at this point in the history
add automatic normalization of expands macro lists
  • Loading branch information
gilesknap authored Apr 10, 2024
2 parents 4d78e9e + 9e00291 commit 90fc6d8
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 6 deletions.
1 change: 1 addition & 0 deletions src/vdct2template/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ def convert(folder: Path, builder_txt: str):
template_path.write_text(text)

# give warnings if there are inconsistent macro substitutions
# NOTE: process_includes() should have already fixed this!
warning |= Expansion.validate_includes()

if warning:
Expand Down
33 changes: 30 additions & 3 deletions src/vdct2template/expansion.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ def __init__(self, filename: Path, folder: Path) -> None:

def parse_expands(self) -> int:
"""
Parse the expands() blocks in the VDB file.
Parse an expands() blocks in a VDB file.
Updates the class attribute substitutions with the macro substitutions parsed.
Updates the class attribute 'substitutions' with the macro substitutions parsed.
Updates the class attribute text with the VDB file text with the expands()
blocks processed into MSI substitute/include statements.
Expand All @@ -50,6 +50,7 @@ def parse_expands(self) -> int:
include_path = self.folder / match[0]
macros = Macros(self.template_path, include_path, match[2])
self.includes.append(macros)
self._normalise_macros(macros)

# replace the expands() block with the MSI directives
self.text = EXPAND.sub(macros.render_include(), self.text, 1)
Expand All @@ -61,9 +62,32 @@ def parse_expands(self) -> int:

return len(expands)

def _normalise_macros(self, macros: Macros):
"""
Given a set of macros for a given expand block, search for all other
instances of an expand against the same template file.
Make sure that this set of macros is consistent with all other instances
by adding in a self referencing macro for any missing ones out of the list
of all macros passed by all instances of such an expansion. (OMLGG!)
"""
vdb_list = self.folder.glob("*.vdb")
for vdb in vdb_list:
vdb_text = vdb.read_text()
expands = EXPAND.findall(vdb_text)
for match in expands:
# match: 0=include path, 1=name, 2=macro text
if match[0] == macros.vdb_path.name:
other_macros = Macros(self.template_path, macros.vdb_path, match[2])
for macro in other_macros.macros:
if macro not in macros.macros:
print(f"adding missing {macro} to {macros.parent.name}")
macros.macros[macro] = f"$({macro})"

def process_includes(self):
"""
Process the included files for this VDB file.
Process the included files for this VDB file. Returns a generator of
tuples of the file and the text to write to the file.
"""
for include in self.includes:
if include.vdb_path.name not in Expansion.processed:
Expand All @@ -77,6 +101,9 @@ def validate_includes(cls) -> bool:
every time they are included. If not then the the replacing of macro
names with _ prefix will be inconsistent between uses of the included
templates and this approach will fail.
NOTE: with the introduction of _normalise_macros() this should not be
necessary but it is left in for now as a backup check.
"""
warning = False
index: Dict[str, Macros] = {}
Expand Down
6 changes: 3 additions & 3 deletions src/vdct2template/regex.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
DROP = re.compile(r"#!.*\n")

# template blocks are also redundant
TEMPLATE = re.compile(r"template *\( *\) * {[\S\s]*?}")
TEMPLATE = re.compile(r"^ *template *\( *\) * {[\S\s]*?}", re.M)

# this extracts the arguments from expand blocks
EXPAND = re.compile(r'expand\("(.*)" *, *([^\)]*)\) *[\s\S]*?{([\s\S]*?)}')
EXPAND = re.compile(r'^ *expand\("(.*)" *, *([^\)]*)\) *[\s\S]*?{([\s\S]*?)}', re.M)

# this extracts the macro entries from an expand block's 3rd argument
MACRO = re.compile(r' *macro *\(([^,]*), *"([^"]*) *')
MACRO = re.compile(r'^ *macro *\(([^,]*), *"([^"]*) *', re.M)

0 comments on commit 90fc6d8

Please sign in to comment.