import os from re import split import subprocess from typing import List from project_man import addLibraryInProject, removeLibraryInProject def getCfFileId(std: str): return "08" if std == "08" else "93" ## Weird behaviour from GHDL, but all vhdl versions besides 08 have [...]93.cf def ghdlEnvExists(std, lib): ## Check if work exists try: os.lstat("work") except: return False ## Check that work is writable if not os.access("work", os.W_OK): print("work is write-protected, please acquire correct permissions") return False cfFileExists = False filesInWork = os.listdir("work") cfFileId = getCfFileId(std) for file in filesInWork: if ".cf" in file and lib in file and cfFileId in file: cfFileExists = True if not cfFileExists: return False ## Nothing bad, continue return True def addVHDLFiles(fileNames: List[str], std: str, lib: str): os.makedirs("work", exist_ok=True) vhdlFiles = [] if ghdlEnvExists(std=std, lib=lib): cfFileId = getCfFileId(std) cfFileName = list(filter(lambda x: ".cf" in x and lib in x and cfFileId in x, os.listdir("work")))[0] cfFilePath = os.path.join("work",cfFileName) currentlyAdded = getCurrentlyAddedFiles(cfFilePath) for fileName in fileNames: if fileName not in currentlyAdded: vhdlFiles.append(fileName) else: addLibraryInProject(lib, ".", std) vhdlFiles = fileNames vhdlFiles = list(filter(lambda x: ".vhd" in x, vhdlFiles)) if len(vhdlFiles) == 0: print("no files to add.") return 0 print(f"adding {vhdlFiles} to library {lib}") command = ["ghdl", "-i", "--workdir=work", f"--work={lib}", f"--std={std}"] + vhdlFiles subprocess.run(command) return 0 def removeVHDLFiles(fileNames: List[str], std: str, lib: str): if not ghdlEnvExists(std=std, lib=lib): return -1 cfFileId = getCfFileId(std) cfFileName = list(filter(lambda x: ".cf" in x and lib in x and cfFileId in x, os.listdir("work")))[0] cfFilePath = os.path.join("work",cfFileName) currentlyAdded = getCurrentlyAddedFiles(cfFilePath) for fileName in fileNames: if fileName not in currentlyAdded: print(f"file {fileName} is not present in {cfFileName}.") return 0 currentlyAdded.remove(fileName) removeCurrentlyAddedFile(fileName, cfFilePath) if len(currentlyAdded) == 0: print("Project is empty, removing GHDL project file and library reference in project") removeLibraryInProject(lib) os.remove(cfFilePath) def getCurrentlyAddedFiles(cfFilePath:str): f = open(cfFilePath,"r") lines = f.readlines() f.close() fileLines = filter(lambda x: "file" in x, lines) files = map(lambda x: split("\" \"",x)[1], fileLines) return list(files) def removeCurrentlyAddedFile(fileName: str, cfFilePath: str): f = open(cfFilePath,"r") lines = f.readlines() f.close() try: mappedLines = list(map(lambda x: fileName in x, lines)) index = mappedLines.index(True) endIndex = len(lines)-1 for x in range(index+1,len(lines)): if "file" in lines[x]: endIndex = x break newLines = [] for x in range(len(lines)): if x < index or x >= endIndex: newLines.append(lines[x]) f = open(cfFilePath, "w") f.writelines(newLines) f.close() except: print(f"Something went wrong when trying to remove {fileName} from {cfFilePath}. Restoring to original configuration") f = open(cfFilePath, "w") f.writelines(lines) f.close()