- Introduced new scripts for project generation and synthesis (dodo.py, generate_prj.py, generate_scr.py, run_xst.py). - Implemented configuration parsing for VHDL sources and project settings (config.py). - Added default configuration values (defaults.py). - Updated .gitignore to include additional file types. - Created test cases for project generation and configuration parsing (test_generate_prj.py, test_generate_scr.py, test_project_cfg.py).
88 lines
2.8 KiB
Python
88 lines
2.8 KiB
Python
from tools.paths import ROOT, PROJECT_CFG, VHDL_LS_TOML
|
|
from pathlib import Path
|
|
from typing import Dict, List, Optional
|
|
import toml
|
|
import re
|
|
from typing import Tuple
|
|
from tools.defaults import with_defaults
|
|
|
|
def parse_vhdl_ls_toml(toml_path: Optional[Path] = None) -> Dict[str, List[Path]]:
|
|
if toml_path is None:
|
|
toml_path = VHDL_LS_TOML
|
|
|
|
if not toml_path.exists():
|
|
raise FileNotFoundError(f"{toml_path} not found.")
|
|
|
|
with open(toml_path, "r", encoding="utf-8") as f:
|
|
raw = toml.load(f)
|
|
|
|
libraries = raw.get("libraries", {})
|
|
parsed: Dict[str, List[Path]] = {}
|
|
|
|
for libname, content in libraries.items():
|
|
if content.get("is_third_party", False):
|
|
continue
|
|
files = content.get("files", [])
|
|
actual_libname = "work" if libname == "lib" else libname
|
|
parsed[actual_libname] = [Path(f) for f in files]
|
|
|
|
return parsed
|
|
|
|
|
|
def parse_project_cfg(cfg_path: Optional[Path] = None) -> Dict[str, str]:
|
|
cfg_path = cfg_path or PROJECT_CFG
|
|
|
|
if not cfg_path.exists():
|
|
raise FileNotFoundError(f"{cfg_path} not found.")
|
|
|
|
result: Dict[str, str] = {}
|
|
ignored_keys = {"VHDSOURCE", "VSOURCE", "VHDTEST", "VTEST"}
|
|
|
|
with cfg_path.open("r", encoding="utf-8") as f:
|
|
for line in f:
|
|
line = line.strip()
|
|
|
|
# Kommentare und Leerzeilen überspringen
|
|
if not line or line.startswith("#"):
|
|
continue
|
|
|
|
if "+=" in line:
|
|
key, value = map(str.strip, line.split("+=", 1))
|
|
if key in ignored_keys:
|
|
continue
|
|
if key in result:
|
|
result[key] += f" {value}"
|
|
else:
|
|
result[key] = value
|
|
elif "=" in line:
|
|
key, value = map(str.strip, line.split("=", 1))
|
|
if key in ignored_keys:
|
|
continue
|
|
result[key] = value
|
|
|
|
return result
|
|
|
|
def get_vhdl_sources_and_tests() -> Tuple[Dict[str, List[Path]], Dict[str, List[Path]]]:
|
|
cfg = with_defaults(parse_project_cfg())
|
|
test_filter = cfg.get("TEST_FILTER", r"^tests/|_tb\.vhd$") # Default-Fallback
|
|
|
|
try:
|
|
pattern = re.compile(test_filter)
|
|
except re.error as e:
|
|
raise ValueError(f"Invalid TEST_FILTER regex: {e}")
|
|
|
|
all_sources = parse_vhdl_ls_toml()
|
|
|
|
normal_sources: Dict[str, List[Path]] = {}
|
|
test_sources: Dict[str, List[Path]] = {}
|
|
|
|
for lib, files in all_sources.items():
|
|
for file in files:
|
|
# relative Pfade als Strings prüfen
|
|
rel_path = str(file)
|
|
if pattern.search(rel_path):
|
|
test_sources.setdefault(lib, []).append(file)
|
|
else:
|
|
normal_sources.setdefault(lib, []).append(file)
|
|
|
|
return normal_sources, test_sources |