Skip to content

Commit 8ee15f6

Browse files
committed
Overwrite more BinaryPlatform functions
1 parent 58cbd25 commit 8ee15f6

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed

src/riscv64.jl

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,95 @@ BinaryPlatforms.arch_march_isa_mapping["riscv64"] =
8282
["riscv64" => get_set("riscv64", "riscv64")]
8383

8484
end
85+
function Base.parse(::Type{Platform}, triplet::AbstractString; validate_strict::Bool = false)
86+
# Helper function to collapse dictionary of mappings down into a regex of
87+
# named capture groups joined by "|" operators
88+
c(mapping) = string("(",join(["(?<$k>$v)" for (k, v) in mapping], "|"), ")")
89+
90+
# We're going to build a mondo regex here to parse everything:
91+
triplet_regex = Regex(string(
92+
"^",
93+
# First, the core triplet; arch/os/libc/call_abi
94+
c(arch_mapping),
95+
c(os_mapping),
96+
c(libc_mapping),
97+
c(call_abi_mapping),
98+
# Next, optional things, like libgfortran/libstdcxx/cxxstring abi
99+
c(libgfortran_version_mapping),
100+
c(cxxstring_abi_mapping),
101+
c(libstdcxx_version_mapping),
102+
# Finally, the catch-all for extended tags
103+
"(?<tags>(?:-[^-]+\\+[^-]+)*)?",
104+
"\$",
105+
))
106+
107+
m = match(triplet_regex, triplet)
108+
if m !== nothing
109+
# Helper function to find the single named field within the giant regex
110+
# that is not `nothing` for each mapping we give it.
111+
get_field(m, mapping) = begin
112+
for k in keys(mapping)
113+
if m[k] !== nothing
114+
# Convert our sentinel `nothing` values to actual `nothing`
115+
if endswith(k, "_nothing")
116+
return nothing
117+
end
118+
# Convert libgfortran/libstdcxx version numbers
119+
if startswith(k, "libgfortran")
120+
return VersionNumber(parse(Int,k[12:end]))
121+
elseif startswith(k, "libstdcxx")
122+
return VersionNumber(3, 4, parse(Int,m[k][11:end]))
123+
else
124+
return k
125+
end
126+
end
127+
end
128+
end
129+
130+
# Extract the information we're interested in:
131+
arch = get_field(m, arch_mapping)
132+
os = get_field(m, os_mapping)
133+
libc = get_field(m, libc_mapping)
134+
call_abi = get_field(m, call_abi_mapping)
135+
libgfortran_version = get_field(m, libgfortran_version_mapping)
136+
libstdcxx_version = get_field(m, libstdcxx_version_mapping)
137+
cxxstring_abi = get_field(m, cxxstring_abi_mapping)
138+
function split_tags(tagstr)
139+
tag_fields = filter(!isempty, split(tagstr, "-"))
140+
if isempty(tag_fields)
141+
return Pair{String,String}[]
142+
end
143+
return map(v -> Symbol(v[1]) => v[2], split.(tag_fields, "+"))
144+
end
145+
tags = split_tags(m["tags"])
146+
147+
# Special parsing of os version number, if any exists
148+
function extract_os_version(os_name, pattern)
149+
m_osvn = match(pattern, m[os_name])
150+
if m_osvn !== nothing
151+
return VersionNumber(m_osvn.captures[1])
152+
end
153+
return nothing
154+
end
155+
os_version = nothing
156+
if os == "macos"
157+
os_version = extract_os_version("macos", r".*darwin([\d\.]+)")
158+
end
159+
if os == "freebsd"
160+
os_version = extract_os_version("freebsd", r".*freebsd([\d.]+)")
161+
end
162+
163+
return Platform(
164+
arch, os;
165+
validate_strict,
166+
libc,
167+
call_abi,
168+
libgfortran_version,
169+
cxxstring_abi,
170+
libstdcxx_version,
171+
os_version,
172+
tags...,
173+
)
174+
end
175+
throw(ArgumentError("Platform `$(triplet)` is not an officially supported platform"))
176+
end

0 commit comments

Comments
 (0)