107 lines
3.7 KiB
Python
107 lines
3.7 KiB
Python
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()
|