fix flex errors on mac when switching between system and homebrew

This commit is contained in:
Tim Paine 2026-05-15 12:36:27 -07:00
parent 4e853d8cb6
commit 13ad58351a
2 changed files with 46 additions and 9 deletions

View File

@ -267,6 +267,7 @@ Thomas Aldrian
Thomas Brown
Thomas Dybdahl Ahle
Tim Hutt
Tim Paine
Tim Snyder
Tobias Jensen
Tobias Rosenkranz

View File

@ -12,10 +12,48 @@
######################################################################
# DESCRIPTION: Edits flex output to get around various broken flex issues.
import os
import re
import subprocess
import sys
import platform
def _flexlexer_uses_size_t() -> bool:
"""Return True if the FlexLexer.h that will be used declares LexerInput with size_t."""
candidates = []
env_paths = os.environ.get("CPATH", "") + os.pathsep + os.environ.get("CPLUS_INCLUDE_PATH", "")
for d in env_paths.split(os.pathsep):
if d:
candidates.append(os.path.join(d, "FlexLexer.h"))
if platform.system() == "Darwin":
try:
sdk = subprocess.check_output(["xcrun", "--show-sdk-path"],
stderr=subprocess.DEVNULL).decode().strip()
if sdk:
candidates.append(os.path.join(sdk, "usr", "include", "FlexLexer.h"))
except (OSError, subprocess.CalledProcessError):
pass
candidates.extend([
"/opt/homebrew/include/FlexLexer.h",
"/usr/local/include/FlexLexer.h",
])
candidates.extend(["/usr/include/FlexLexer.h"])
for path in candidates:
try:
with open(path, "r", encoding="utf-8", errors="ignore") as fh:
text = fh.read()
except OSError:
continue
if re.search(r"\bLexerInput\s*\(\s*char\s*\*\s*\w*\s*,\s*size_t\b", text):
return True
if re.search(r"\bLexerInput\s*\(\s*char\s*\*\s*\w*\s*,\s*int\b", text):
return False
return False
_LEXER_USES_SIZE_T = _flexlexer_uses_size_t()
for line in sys.stdin:
# Fix flex 2.6.1 warning
line = re.sub(r'for \( i = 0; i < _yybytes_len; \+\+i \)',
@ -48,14 +86,12 @@ for line in sys.stdin:
line = re.sub(r'(#line \d+ ".*)_pretmp', r'\1', line)
# Fix 'register' storage class specifier is deprecated and incompatible with C++17
line = re.sub(r'register ', '', line)
# Change int to size_t on LexerInput/LexerOutput when using macOS Tahoe
if platform.system() == "Darwin":
try:
osv = platform.mac_ver()[0] # Example "26.2"
if len(osv) > 2 and osv[2] == "." and int(osv[:2]) >= 26:
if "::LexerInput(" in line or "::LexerOutput(" in line:
line = re.sub(r'int ', r'size_t ', line)
except IndexError as e:
print(f"Unexpected index error {e}")
# Change int to size_t on LexerInput/LexerOutput when the FlexLexer.h in use
# declares them with size_t (e.g. macOS Tahoe's system flex). Skip when the
# actual FlexLexer.h still uses int (e.g. Homebrew flex 2.6.4) to avoid an
# out-of-line-definition mismatch.
if _LEXER_USES_SIZE_T:
if "::LexerInput(" in line or "::LexerOutput(" in line:
line = re.sub(r'int ', r'size_t ', line)
print(line, end='')