Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add automatic normalization of expands macro lists #1

Merged
merged 1 commit into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)