parse
Function parameters
Parameters
Type definitions in this namespace
Types
Functions in this namespace
Functions
- parseCpuArch
- Similar to `parse` except instead of fully parsing, it only determines the CPU
- parseVersion
- Similar to `SemanticVersion.parse`, but with following changes:
- serializeCpu
- Renders the query into a textual representation that can be parsed via the
Source
Implementation
pub fn parse(args: ParseOptions) !Query {
var dummy_diags: ParseOptions.Diagnostics = undefined;
const diags = args.diagnostics orelse &dummy_diags;
var result: Query = .{
.dynamic_linker = Target.DynamicLinker.init(args.dynamic_linker),
};
var it = mem.splitScalar(u8, args.arch_os_abi, '-');
const arch_name = it.first();
const arch_is_native = mem.eql(u8, arch_name, "native");
if (!arch_is_native) {
result.cpu_arch = std.meta.stringToEnum(Target.Cpu.Arch, arch_name) orelse {
diags.unknown_architecture_name = arch_name;
return error.UnknownArchitecture;
};
}
const arch = result.cpu_arch orelse builtin.cpu.arch;
diags.arch = arch;
if (it.next()) |os_text| {
try parseOs(&result, diags, os_text);
} else if (!arch_is_native) {
return error.MissingOperatingSystem;
}
const opt_abi_text = it.next();
if (opt_abi_text) |abi_text| {
var abi_it = mem.splitScalar(u8, abi_text, '.');
const abi = std.meta.stringToEnum(Target.Abi, abi_it.first()) orelse
return error.UnknownApplicationBinaryInterface;
result.abi = abi;
diags.abi = abi;
const abi_ver_text = abi_it.rest();
if (abi_it.next() != null) {
if (abi.isGnu()) {
result.glibc_version = parseVersion(abi_ver_text) catch |err| switch (err) {
error.Overflow => return error.InvalidAbiVersion,
error.InvalidVersion => return error.InvalidAbiVersion,
};
} else if (abi.isAndroid()) {
result.android_api_level = std.fmt.parseUnsigned(u32, abi_ver_text, 10) catch |err| switch (err) {
error.InvalidCharacter => return error.InvalidVersion,
error.Overflow => return error.Overflow,
};
} else {
return error.InvalidAbiVersion;
}
}
}
if (it.next() != null) return error.UnexpectedExtraField;
if (args.cpu_features) |cpu_features| {
const all_features = arch.allFeaturesList();
var index: usize = 0;
while (index < cpu_features.len and
cpu_features[index] != '+' and
cpu_features[index] != '-')
{
index += 1;
}
const cpu_name = cpu_features[0..index];
diags.cpu_name = cpu_name;
const add_set = &result.cpu_features_add;
const sub_set = &result.cpu_features_sub;
if (mem.eql(u8, cpu_name, "native")) {
result.cpu_model = .native;
} else if (mem.eql(u8, cpu_name, "baseline")) {
result.cpu_model = .baseline;
} else {
result.cpu_model = .{ .explicit = try arch.parseCpuModel(cpu_name) };
}
while (index < cpu_features.len) {
const op = cpu_features[index];
const set = switch (op) {
'+' => add_set,
'-' => sub_set,
else => unreachable,
};
index += 1;
const start = index;
while (index < cpu_features.len and
cpu_features[index] != '+' and
cpu_features[index] != '-')
{
index += 1;
}
const feature_name = cpu_features[start..index];
for (all_features, 0..) |feature, feat_index_usize| {
const feat_index = @as(Target.Cpu.Feature.Set.Index, @intCast(feat_index_usize));
if (mem.eql(u8, feature_name, feature.name)) {
set.addFeature(feat_index);
break;
}
} else {
diags.unknown_feature_name = feature_name;
return error.UnknownCpuFeature;
}
}
}
if (args.object_format) |ofmt_name| {
result.ofmt = std.meta.stringToEnum(Target.ObjectFormat, ofmt_name) orelse
return error.UnknownObjectFormat;
}
return result;
}