Skip to content
Closed
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
56 changes: 53 additions & 3 deletions JsonPreprocessor/CJsonPreprocessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ def __init__(self, syntax: CSyntaxType = CSyntaxType.python , currentCfg : dict

Internally used to aggregate imported json files.
"""
import builtins
import keyword
self.lDataTypes = [name for name, value in vars(builtins).items() if isinstance(value, type)]
self.lDataTypes.append(keyword.kwlist)
self.lImportedFiles = []
self.recursive_level = 0
self.syntax = syntax
Expand Down Expand Up @@ -344,6 +348,31 @@ def replacer(match):
return sContentCleaned


def __checkParamName(self, sInput: str) -> str:
"""
Checks a parameter name, in case the name is conflict with Python keywords, the temporary prefix
will be added to avoid any potential issues. This temporary prefix is removed when updating returned
Json object.

**Args:**

**sInput** (*string*)

**Returns:**

**sInput** (*string*)
"""

pattern = "\${\s*([0-9A-Za-z_]+[0-9A-Za-z\.\-_]*)\s*}"
lParams = re.findall(pattern, sInput)
for param in lParams:
if "." not in param and param in self.lDataTypes:
sInput = re.sub(param, "JPavoidDataType_" + param, sInput, count=1)
if "." in param and "JPavoidDataType_" + param.split('.')[0] in globals():
sInput = re.sub(param, "JPavoidDataType_" + param, sInput, count=1)
return sInput


def __nestedParamHandler(self, sInputStr : str, bKey = False) -> list:
'''
This method handles nested variables in parameter names or values. Variable syntax is ${Variable_Name}.
Expand Down Expand Up @@ -503,6 +532,8 @@ def __jsonUpdated(k, v, oJson, bNested, keyNested = ''):
except:
raise Exception(f"Could not set variable '{k}' with value '{v}'!")

if "JPavoidDataType_" in k:
k = re.sub("JPavoidDataType_", "", k)
if isinstance(v, str):
sExec = "oJson['" + k.split('[', 1)[0] + "'][" + k.split('[', 1)[1] + " = \"" + v + "\""
else:
Expand All @@ -512,24 +543,34 @@ def __jsonUpdated(k, v, oJson, bNested, keyNested = ''):
except:
pass
else:
if "JPavoidDataType_" in k:
k = re.sub("JPavoidDataType_", "", k)
oJson[k] = v

else:
if bNested:
if "JPavoidDataType_" in k:
k = re.sub("JPavoidDataType_", "", k)
oJson[k] = v


if bool(self.currentCfg) and not recursive:
for k, v in self.currentCfg.items():
if k in self.lDataTypes:
k = "JPavoidDataType_" + k
globals().update({k:v})

tmpJson = copy.deepcopy(oJson)
for k, v in tmpJson.items():
keyNested = ''
if re.match('.*\${\s*', k.lower()):
keyNested = k
pattern = "\${\s*[0-9A-Za-z_]+[0-9A-Za-z\.\-_]*\s*}(\[\s*.+\s*\])*"
if re.match("str\(\s*\${.+", k.lower()):
k = re.sub("str\(\s*(\${.+)\s*\)", "\\1", k)
k = re.sub("str\(\s*(" + pattern + ")\s*\)", "\\1", k)
if len(re.findall(pattern, k.lower())) > 1 or k.count('{') != k.count('}'):
raise Exception(f"Could not overwrite parameter {k} due to wrong format.\n \
Please check key '{k}' in config file!!!")
k = self.__checkParamName(k)
keyAfterProcessed = self.__nestedParamHandler(k, bKey=True)
k = re.sub('^\s*\${\s*(.*?)\s*}', '\\1', keyAfterProcessed[0])

Expand All @@ -545,6 +586,7 @@ def __jsonUpdated(k, v, oJson, bNested, keyNested = ''):
if re.match("str\(\s*\${.+", item.lower()):
item = re.sub("str\(\s*(\${.+)\s*\)", "\\1", item)
bStringValue = True
item = self.__checkParamName(item)
itemAfterProcessed = self.__nestedParamHandler(item)
tmpItemAfterProcessed = re.sub('\${\s*(.*?)\s*}', '\\1', itemAfterProcessed[0])
sExec = "value = " + tmpItemAfterProcessed if isinstance(tmpItemAfterProcessed, str) else \
Expand All @@ -570,6 +612,7 @@ def __jsonUpdated(k, v, oJson, bNested, keyNested = ''):
if re.search("(str\(\s*" + pattern + "\))", v.lower()):
v = re.sub("str\(\s*(" + pattern + ")\s*\)", "\\1", v)
bStringValue = True
v = self.__checkParamName(v)
valueAfterProcessed = self.__nestedParamHandler(v)
for valueProcessed in valueAfterProcessed:
tmpValueAfterProcessed = re.sub('\\${\s*(.*?)\s*}', '\\1', valueProcessed)
Expand Down Expand Up @@ -617,10 +660,14 @@ def __checkAndUpdateKeyValue(self, sInputStr: str) -> str:
for nestedParam in lNestedParam:
self.lNestedParams.append(nestedParam[0])
sInputStr = re.sub("(" + pattern + ")", "str(\\1)", sInputStr)
elif re.search(pattern, sInputStr.lower()):
elif re.search("^\s*" + pattern + "\s*\]*\}*,*\s*$", sInputStr.lower()):
sInputStr = re.sub("(" + pattern + ")", "\"\\1\"", sInputStr)
nestedParam = re.sub("^\s*\"(.+)\"\s*.*$", "\\1", sInputStr)
self.lNestedParams.append(nestedParam)
else:
if len(re.findall(pattern, sInputStr.lower()))>1:
raise Exception(f"Key name or value is a mix of nested parameters and hard coded parts. \n \
The entire expression {sInputStr.strip()} must be enclosed in quotes")

sOutput = sInputStr
return sOutput
Expand Down Expand Up @@ -784,6 +831,8 @@ def __handleListElements(sInput : str) -> str:

if masterFile:
for k, v in oJson.items():
if k in self.lDataTypes:
k = "JPavoidDataType_" + k
globals().update({k:v})
oJson, bNested = self.__updateAndReplaceNestedParam(oJson)
for k, v in self.dUpdatedParams.items():
Expand All @@ -804,6 +853,7 @@ def __handleListElements(sInput : str) -> str:

# Checking availability of nested parameters before updating and replacing.
for param in self.lNestedParams:
param = self.__checkParamName(param)
parseNestedParam = self.__nestedParamHandler(param)
tmpParseNestedParam = re.sub('\\${\s*(.*?)\s*}', '\\1', parseNestedParam[0])
sExec = "value = " + tmpParseNestedParam if isinstance(tmpParseNestedParam, str) else \
Expand Down