mirror of
https://github.com/facebook/zstd.git
synced 2025-08-07 06:23:00 +03:00
[freestanding] Improve macro resolution to handle #if X
This commit is contained in:
@@ -78,7 +78,7 @@ class PartialPreprocessor(object):
|
|||||||
fr"\s*#\s*{ELIF_GROUP}if\s+(?P<not>!)?\s*defined\s*\(\s*{MACRO_GROUP}\s*\)\s*{OP_GROUP}"
|
fr"\s*#\s*{ELIF_GROUP}if\s+(?P<not>!)?\s*defined\s*\(\s*{MACRO_GROUP}\s*\)\s*{OP_GROUP}"
|
||||||
)
|
)
|
||||||
self._if_defined_value = re.compile(
|
self._if_defined_value = re.compile(
|
||||||
fr"\s*#\s*if\s+defined\s*\(\s*{MACRO_GROUP}\s*\)\s*"
|
fr"\s*#\s*{ELIF_GROUP}if\s+defined\s*\(\s*{MACRO_GROUP}\s*\)\s*"
|
||||||
fr"(?P<op>&&)\s*"
|
fr"(?P<op>&&)\s*"
|
||||||
fr"(?P<openp>\()?\s*"
|
fr"(?P<openp>\()?\s*"
|
||||||
fr"(?P<macro2>[a-zA-Z_][a-zA-Z_0-9]*)\s*"
|
fr"(?P<macro2>[a-zA-Z_][a-zA-Z_0-9]*)\s*"
|
||||||
@@ -86,6 +86,9 @@ class PartialPreprocessor(object):
|
|||||||
fr"(?P<value>[0-9]*)\s*"
|
fr"(?P<value>[0-9]*)\s*"
|
||||||
fr"(?P<closep>\))?\s*"
|
fr"(?P<closep>\))?\s*"
|
||||||
)
|
)
|
||||||
|
self._if_true = re.compile(
|
||||||
|
fr"\s*#\s*{ELIF_GROUP}if\s+{MACRO_GROUP}\s*{OP_GROUP}"
|
||||||
|
)
|
||||||
|
|
||||||
self._c_comment = re.compile(r"/\*.*?\*/")
|
self._c_comment = re.compile(r"/\*.*?\*/")
|
||||||
self._cpp_comment = re.compile(r"//")
|
self._cpp_comment = re.compile(r"//")
|
||||||
@@ -262,10 +265,14 @@ class PartialPreprocessor(object):
|
|||||||
line = self._inlines[idx]
|
line = self._inlines[idx]
|
||||||
sline = self._strip_comments(line)
|
sline = self._strip_comments(line)
|
||||||
m = self._ifdef.fullmatch(sline)
|
m = self._ifdef.fullmatch(sline)
|
||||||
|
if_true = False
|
||||||
if m is None:
|
if m is None:
|
||||||
m = self._if_defined_value.fullmatch(sline)
|
m = self._if_defined_value.fullmatch(sline)
|
||||||
if m is None:
|
if m is None:
|
||||||
m = self._if_defined.match(sline)
|
m = self._if_defined.match(sline)
|
||||||
|
if m is None:
|
||||||
|
m = self._if_true.match(sline)
|
||||||
|
if_true = (m is not None)
|
||||||
if m is None:
|
if m is None:
|
||||||
outlines.append(line)
|
outlines.append(line)
|
||||||
idx += 1
|
idx += 1
|
||||||
@@ -273,84 +280,116 @@ class PartialPreprocessor(object):
|
|||||||
|
|
||||||
groups = m.groupdict()
|
groups = m.groupdict()
|
||||||
macro = groups['macro']
|
macro = groups['macro']
|
||||||
ifdef = groups.get('not') is None
|
|
||||||
elseif = groups.get('elif') is not None
|
|
||||||
op = groups.get('op')
|
op = groups.get('op')
|
||||||
|
|
||||||
macro2 = groups.get('macro2')
|
|
||||||
cmp = groups.get('cmp')
|
|
||||||
value = groups.get('value')
|
|
||||||
openp = groups.get('openp')
|
|
||||||
closep = groups.get('closep')
|
|
||||||
|
|
||||||
if not (macro in self._defs or macro in self._undefs):
|
if not (macro in self._defs or macro in self._undefs):
|
||||||
outlines.append(line)
|
outlines.append(line)
|
||||||
idx += 1
|
idx += 1
|
||||||
continue
|
continue
|
||||||
|
|
||||||
defined = macro in self._defs
|
defined = macro in self._defs
|
||||||
is_true = (ifdef == defined)
|
|
||||||
resolved = True
|
|
||||||
if op is not None:
|
|
||||||
if op == '&&':
|
|
||||||
resolved = not is_true
|
|
||||||
else:
|
|
||||||
assert op == '||'
|
|
||||||
resolved = is_true
|
|
||||||
|
|
||||||
if macro2 is not None and not resolved:
|
# Needed variables set:
|
||||||
assert ifdef and defined and op == '&&' and cmp is not None
|
# resolved: Is the statement fully resolved?
|
||||||
# If the statment is true, but we have a single value check, then
|
# is_true: If resolved, is the statement true?
|
||||||
# check the value.
|
ifdef = False
|
||||||
|
if if_true:
|
||||||
|
if not defined:
|
||||||
|
outlines.append(line)
|
||||||
|
idx += 1
|
||||||
|
continue
|
||||||
|
|
||||||
defined_value = self._defs[macro]
|
defined_value = self._defs[macro]
|
||||||
are_ints = True
|
is_int = True
|
||||||
try:
|
try:
|
||||||
defined_value = int(defined_value)
|
defined_value = int(defined_value)
|
||||||
value = int(value)
|
|
||||||
except TypeError:
|
except TypeError:
|
||||||
are_ints = False
|
is_int = False
|
||||||
except ValueError:
|
except ValueError:
|
||||||
are_ints = False
|
is_int = False
|
||||||
if (
|
|
||||||
macro == macro2 and
|
resolved = is_int
|
||||||
((openp is None) == (closep is None)) and
|
is_true = (defined_value != 0)
|
||||||
are_ints
|
|
||||||
):
|
if resolved and op is not None:
|
||||||
resolved = True
|
if op == '&&':
|
||||||
if cmp == '<':
|
resolved = not is_true
|
||||||
is_true = defined_value < value
|
|
||||||
elif cmp == '<=':
|
|
||||||
is_true = defined_value <= value
|
|
||||||
elif cmp == '==':
|
|
||||||
is_true = defined_value == value
|
|
||||||
elif cmp == '!=':
|
|
||||||
is_true = defined_value != value
|
|
||||||
elif cmp == '>=':
|
|
||||||
is_true = defined_value >= value
|
|
||||||
elif cmp == '>':
|
|
||||||
is_true = defined_value > value
|
|
||||||
else:
|
else:
|
||||||
resolved = False
|
assert op == '||'
|
||||||
|
resolved = is_true
|
||||||
|
|
||||||
if op is not None and not resolved:
|
else:
|
||||||
# Remove the first op in the line + spaces
|
ifdef = groups.get('not') is None
|
||||||
if op == '&&':
|
elseif = groups.get('elif') is not None
|
||||||
opre = op
|
|
||||||
else:
|
|
||||||
assert op == '||'
|
|
||||||
opre = r'\|\|'
|
|
||||||
needle = re.compile(fr"(?P<if>\s*#\s*(el)?if\s+).*?(?P<op>{opre}\s*)")
|
|
||||||
match = needle.match(line)
|
|
||||||
assert match is not None
|
|
||||||
newline = line[:match.end('if')] + line[match.end('op'):]
|
|
||||||
|
|
||||||
self._log(f"\tHardwiring partially resolved {macro}")
|
macro2 = groups.get('macro2')
|
||||||
self._log(f"\t\t- {line[:-1]}")
|
cmp = groups.get('cmp')
|
||||||
self._log(f"\t\t+ {newline[:-1]}")
|
value = groups.get('value')
|
||||||
|
openp = groups.get('openp')
|
||||||
|
closep = groups.get('closep')
|
||||||
|
|
||||||
outlines.append(newline)
|
is_true = (ifdef == defined)
|
||||||
idx += 1
|
resolved = True
|
||||||
continue
|
if op is not None:
|
||||||
|
if op == '&&':
|
||||||
|
resolved = not is_true
|
||||||
|
else:
|
||||||
|
assert op == '||'
|
||||||
|
resolved = is_true
|
||||||
|
|
||||||
|
if macro2 is not None and not resolved:
|
||||||
|
assert ifdef and defined and op == '&&' and cmp is not None
|
||||||
|
# If the statment is true, but we have a single value check, then
|
||||||
|
# check the value.
|
||||||
|
defined_value = self._defs[macro]
|
||||||
|
are_ints = True
|
||||||
|
try:
|
||||||
|
defined_value = int(defined_value)
|
||||||
|
value = int(value)
|
||||||
|
except TypeError:
|
||||||
|
are_ints = False
|
||||||
|
except ValueError:
|
||||||
|
are_ints = False
|
||||||
|
if (
|
||||||
|
macro == macro2 and
|
||||||
|
((openp is None) == (closep is None)) and
|
||||||
|
are_ints
|
||||||
|
):
|
||||||
|
resolved = True
|
||||||
|
if cmp == '<':
|
||||||
|
is_true = defined_value < value
|
||||||
|
elif cmp == '<=':
|
||||||
|
is_true = defined_value <= value
|
||||||
|
elif cmp == '==':
|
||||||
|
is_true = defined_value == value
|
||||||
|
elif cmp == '!=':
|
||||||
|
is_true = defined_value != value
|
||||||
|
elif cmp == '>=':
|
||||||
|
is_true = defined_value >= value
|
||||||
|
elif cmp == '>':
|
||||||
|
is_true = defined_value > value
|
||||||
|
else:
|
||||||
|
resolved = False
|
||||||
|
|
||||||
|
if op is not None and not resolved:
|
||||||
|
# Remove the first op in the line + spaces
|
||||||
|
if op == '&&':
|
||||||
|
opre = op
|
||||||
|
else:
|
||||||
|
assert op == '||'
|
||||||
|
opre = r'\|\|'
|
||||||
|
needle = re.compile(fr"(?P<if>\s*#\s*(el)?if\s+).*?(?P<op>{opre}\s*)")
|
||||||
|
match = needle.match(line)
|
||||||
|
assert match is not None
|
||||||
|
newline = line[:match.end('if')] + line[match.end('op'):]
|
||||||
|
|
||||||
|
self._log(f"\tHardwiring partially resolved {macro}")
|
||||||
|
self._log(f"\t\t- {line[:-1]}")
|
||||||
|
self._log(f"\t\t+ {newline[:-1]}")
|
||||||
|
|
||||||
|
outlines.append(newline)
|
||||||
|
idx += 1
|
||||||
|
continue
|
||||||
|
|
||||||
# Skip any statements we cannot fully compute
|
# Skip any statements we cannot fully compute
|
||||||
if not resolved:
|
if not resolved:
|
||||||
|
@@ -1902,7 +1902,7 @@ ZSTD_reduceTable_internal (U32* const table, U32 const size, U32 const reducerVa
|
|||||||
assert((size & (ZSTD_ROWSIZE-1)) == 0); /* multiple of ZSTD_ROWSIZE */
|
assert((size & (ZSTD_ROWSIZE-1)) == 0); /* multiple of ZSTD_ROWSIZE */
|
||||||
assert(size < (1U<<31)); /* can be casted to int */
|
assert(size < (1U<<31)); /* can be casted to int */
|
||||||
|
|
||||||
#if defined (MEMORY_SANITIZER) && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE)
|
#if ZSTD_MEMORY_SANITIZER && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE)
|
||||||
/* To validate that the table re-use logic is sound, and that we don't
|
/* To validate that the table re-use logic is sound, and that we don't
|
||||||
* access table space that we haven't cleaned, we re-"poison" the table
|
* access table space that we haven't cleaned, we re-"poison" the table
|
||||||
* space every time we mark it dirty.
|
* space every time we mark it dirty.
|
||||||
|
Reference in New Issue
Block a user