Skip to content
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
131 changes: 131 additions & 0 deletions src/core/model_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,137 @@ def FileLine__clear(

return __class__.Helper__ClearFileLine(cfgData, fileLineData)

# --------------------------------------------------------------------
class tagFindCtx:
m_processedFiles: typing.Optional[typing.Set[str]]

def __init__(self):
self.m_processedFiles = None
return

def reg_file(
self,
filePath: str,
) -> bool:
assert type(filePath) is str
assert filePath != ""

if self.m_processedFiles is None:
self.m_processedFiles = set()
elif filePath in self.m_processedFiles:
return False

self.m_processedFiles.add(filePath)
return True

# --------------------------------------------------------------------
@staticmethod
def File__FindSimpleOption(
findCtx: tagFindCtx,
fileData: PgCfgModel__FileData,
optionName: str,
enterIntoIncludes: bool,
) -> typing.Optional[PgCfgModel__OptionData]:
assert type(findCtx) is __class__.tagFindCtx
assert type(fileData) is PgCfgModel__FileData
assert type(fileData.m_Lines) is list
assert type(optionName) is str
assert type(enterIntoIncludes) is bool

if not findCtx.reg_file(fileData.m_Path):
return None

stack: typing.List[
typing.Tuple[
PgCfgModel__FileData,
int,
]
] = []

top_fileData = fileData
top_index = len(fileData.m_Lines)

while True:
assert top_index <= len(top_fileData.m_Lines)
assert top_index >= 0

nextFile: typing.Optional[PgCfgModel__FileData] = None

while top_index > 0:
top_index -= 1

lineData = top_fileData.m_Lines[top_index]

if len(lineData.m_Items) == 0:
continue

assert len(lineData.m_Items) > 0
assert len(lineData.m_Items) <= 2

firstItem = lineData.m_Items[0]
assert firstItem is not None
assert firstItem.m_Element is not None

# Debug checks
if len(lineData.m_Items) == 1:
pass
else:
assert len(lineData.m_Items) == 2
assert lineData.m_Items[1] is not None
assert lineData.m_Items[1].m_Element is not None
assert (
type(lineData.m_Items[1].m_Element) is PgCfgModel__CommentData
)
pass

if type(firstItem.m_Element) is PgCfgModel__OptionData:
if firstItem.m_Element.m_Name != optionName:
continue

return firstItem.m_Element # <--------- BINGO

if type(firstItem.m_Element) is PgCfgModel__IncludeData:
if not enterIntoIncludes:
# Stop searching upwards: any option defined above an include
# might be overridden by that included file.
return None # <--------- FAIL

if not findCtx.reg_file(firstItem.m_Element.m_File.m_Path):
continue

nextFile = firstItem.m_Element.m_File
break

if type(firstItem.m_Element) is PgCfgModel__CommentData:
assert len(lineData.m_Items) == 1
continue

BugCheckError.UnkObjectDataType(
type(firstItem.m_Element),
)

if nextFile is None:
assert top_index == 0

if len(stack) == 0:
return None # <--------- FAIL

top = stack.pop()
assert top is not None
top_fileData = top[0]
top_index = top[1]
continue

assert nextFile is not None
assert top_index >= 0
assert top_index < len(top_fileData.m_Lines)

stack.append((top_fileData, top_index))

top_fileData = nextFile
top_index = len(nextFile.m_Lines)
continue

# --------------------------------------------------------------------
@staticmethod
def File__add_Option(
Expand Down
17 changes: 10 additions & 7 deletions src/implementation/v00/configuration_base_ds_strict.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,22 +129,25 @@ def GetOptionValue__Simple(

# -------------------------------------- FILE DATA
if type(sourceData) is PgCfgModel__FileData:
fileData = sourceData
assert sourceData.IsAlive()

assert fileData.IsAlive()
assert fileData.m_OptionsByName is not None
assert type(fileData.m_OptionsByName) is PgCfgModel__MultiIndex
if optionName not in cfg.m_Data.m_AllOptionsByName.keys():
return None

optionData = __class__.Helper__FindSimpleOption(
cfg,
fileData.m_OptionsByName,
findCtx = PgCfgModel__ModelUtils.tagFindCtx()

optionData = PgCfgModel__ModelUtils.File__FindSimpleOption(
findCtx,
sourceData,
optionName,
enterIntoIncludes=True,
)

if optionData is not None:
assert type(optionData) is PgCfgModel__OptionData
assert optionData.IsAlive()
assert optionData.m_Value is not None
assert optionData.m_Name == optionName
return __class__.Helper__PrepareGetValue(
cfg,
optionData.m_Name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ def test_002__two_files(
assert file1.m_FileData is load_r1.m_FileData
assert file2.m_FileData is load_r2.m_FileData

assert file1.GetOptionValue("port") is None
assert file1.GetOptionValue("port") == 123
assert file2.GetOptionValue("port") == 123
return

Expand Down Expand Up @@ -296,7 +296,7 @@ def test_003__two_files__duplication_and_cycles(
file1 = cfg.get_AllFiles().GetFileByName(C_FILE_NAME1)
file2 = cfg.get_AllFiles().GetFileByName(C_FILE_NAME2)

assert file1.GetOptionValue("port") is None
assert file1.GetOptionValue("port") == 123
assert file2.GetOptionValue("port") == 123
return

Expand Down
Loading