Skip to content

Commit

Permalink
edk2toollib/uefi/edk2/parsers: enhancements (#419)
Browse files Browse the repository at this point in the history
Improves the following parsers in the following ways:

`base_parser.py`: Properly uses ivalue (int value) to check if the string representation of a value was correctly converted to an integer ('1' to 1, '0x0' to 0, etc) when evaluating conditionals

`dsc_parser.py`: register pcds when performing the initial parse responsible for finding define statements. This is necessary to evaluate conditionals that use pcds.
  • Loading branch information
Javagedes authored Oct 2, 2023
1 parent 2536e7f commit 2178650
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 30 deletions.
9 changes: 7 additions & 2 deletions edk2toollib/uefi/edk2/parsers/base_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,12 +240,17 @@ def ComputeResult(self, value, cond, value2):
return (ivalue != ivalue2) and (value != value2)

# check to make sure we only have digits from here on out
if not isinstance(value, int) and not str.isdigit(value):
if value.upper() in ["TRUE", "FALSE"] or value2.upper() in ["TRUE", "FALSE"]:
self.Logger.error(f"Invalid comparison: {value} {cond} {value2}")
self.Logger.debug(f"Invalid comparison: {value} {cond} {value2}")
raise ValueError("Invalid comparison")

if not isinstance(ivalue, int) and not str.isdigit(value):
self.Logger.error(f"{self.__class__}: Unknown value: {value} {ivalue.__class__}")
self.Logger.debug(f"{self.__class__}: Conditional: {value} {cond}{value2}")
raise ValueError("Unknown value")

if not isinstance(value2, int) and not str.isdigit(value2):
if not isinstance(ivalue2, int) and not str.isdigit(value2):
self.Logger.error(f"{self.__class__}: Unknown value: {value2} {ivalue2}")
self.Logger.debug(f"{self.__class__}: Conditional: {value} {cond} {value2}")
raise ValueError("Unknown value")
Expand Down
54 changes: 26 additions & 28 deletions edk2toollib/uefi/edk2/parsers/dsc_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,8 @@ def __ParseLine(self, Line, file_name=None, lineno=None):
p = self.ParseInfPathLib(line_resolved)
self.Libs.append(p)
self.Logger.debug("Found Library in a 64bit BuildOptions Section: %s" % p)
elif "tokenspaceguid" in line_resolved.lower() and \
line_resolved.count('|') > 0 and line_resolved.count('.') > 0:
# should be a pcd statement
p = line_resolved.partition('|')
self.Pcds.append(p[0].strip())
self.PcdValueDict[p[0].strip()] = p[2].strip()
self.Logger.debug("Found a Pcd in a 64bit Module Override section: %s" % p[0].strip())
elif self.RegisterPcds(line_resolved):
self.Logger.debug("Found a Pcd in a 64bit Module Override section")
else:
if (".inf" in line_resolved.lower()):
p = self.ParseInfPathMod(line_resolved)
Expand All @@ -141,13 +136,8 @@ def __ParseLine(self, Line, file_name=None, lineno=None):
if file_name is not None and lineno is not None:
self.LibsEnhanced.append({'file': os.path.normpath(file_name), 'lineno': lineno, 'data': p})
self.Logger.debug("Found Library in a 32bit BuildOptions Section: %s" % p)
elif "tokenspaceguid" in line_resolved.lower() and \
line_resolved.count('|') > 0 and line_resolved.count('.') > 0:
# should be a pcd statement
p = line_resolved.partition('|')
self.Pcds.append(p[0].strip())
self.PcdValueDict[p[0].strip()] = p[2].strip()
self.Logger.debug("Found a Pcd in a 32bit Module Override section: %s" % p[0].strip())
elif self.RegisterPcds(line_resolved):
self.Logger.debug("Found a Pcd in a 32bit Module Override section")

else:
if (".inf" in line_resolved.lower()):
Expand All @@ -169,13 +159,8 @@ def __ParseLine(self, Line, file_name=None, lineno=None):
p = self.ParseInfPathLib(line_resolved)
self.Libs.append(p)
self.Logger.debug("Found Library in a BuildOptions Section: %s" % p)
elif "tokenspaceguid" in line_resolved.lower() and \
line_resolved.count('|') > 0 and line_resolved.count('.') > 0:
# should be a pcd statement
p = line_resolved.partition('|')
self.Pcds.append(p[0].strip())
self.PcdValueDict[p[0].strip()] = p[2].strip()
self.Logger.debug("Found a Pcd in a Module Override section: %s" % p[0].strip())
elif self.RegisterPcds(line_resolved):
self.Logger.debug("Found a Pcd in a Module Override section")

else:
if (".inf" in line_resolved.lower()):
Expand All @@ -196,13 +181,8 @@ def __ParseLine(self, Line, file_name=None, lineno=None):
return (line_resolved, [], None)
# process line in PCD section
elif (self.CurrentSection.upper().startswith("PCDS")):
if "tokenspaceguid" in line_resolved.lower() and \
line_resolved.count('|') > 0 and line_resolved.count('.') > 0:
# should be a pcd statement
p = line_resolved.partition('|')
self.Pcds.append(p[0].strip())
self.PcdValueDict[p[0].strip()] = p[2].strip()
self.Logger.debug("Found a Pcd in a PCD section: %s" % p[0].strip())
if self.RegisterPcds(line_resolved):
self.Logger.debug("Found a Pcd in a PCD section")
return (line_resolved, [], None)
else:
return (line_resolved, [], None)
Expand All @@ -213,6 +193,8 @@ def __ParseDefineLine(self, Line):
return ("", [])

# this line needs to be here to resolve any symbols inside the !include lines, if any
self.RegisterPcds(line_stripped)
line_stripped = self.ReplacePcds(line_stripped)
line_resolved = self.ReplaceVariables(line_stripped)
if (self.ProcessConditional(line_resolved)):
# was a conditional
Expand Down Expand Up @@ -333,6 +315,8 @@ def __ProcessDefines(self, lines):
# otherwise, raise the exception and act normally
if not self._no_fail_mode:
raise
# Reset the PcdValueDict as this was just to find any Defines.
self.PcdValueDict = {}

def _parse_libraries(self):
"""Builds a lookup table of all possible library instances depending on scope.
Expand Down Expand Up @@ -535,3 +519,17 @@ def GetAllDscPaths(self):
They are not all guaranteed to be DSC files
"""
return self._dsc_file_paths

def RegisterPcds(self, line):
"""Reads the line and registers any PCDs found."""
if ("tokenspaceguid" in line.lower() and
line.count('|') > 0 and
line.count('.') > 0):

# should be a pcd statement
p = line.partition('|')
self.Pcds.append(p[0].strip())
self.PcdValueDict[p[0].strip()] = p[2].strip()
self.Logger.debug("Found a Pcd: %s" % p[0].strip())
return True
return False
7 changes: 7 additions & 0 deletions tests.unit/parsers/test_base_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,13 @@ def test_process_conditional_hex_number(self):
self.assertTrue(parser.ProcessConditional("!IF 0x20 == 32"))
self.assertTrue(parser.InActiveCode())
self.assertTrue(parser.ProcessConditional("!endif"))
# check that hex comparisons work
self.assertTrue(parser.ProcessConditional("!IF 0x20 > 0x20"))
self.assertFalse(parser.InActiveCode())
self.assertTrue(parser.ProcessConditional("!endif"))
self.assertTrue(parser.ProcessConditional("!IF 0x20 >= 0x20"))
self.assertTrue(parser.InActiveCode())
self.assertTrue(parser.ProcessConditional("!endif"))

def test_process_conditional_greater_than(self):
parser = BaseParser("")
Expand Down

0 comments on commit 2178650

Please sign in to comment.