mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-04-26 13:01:34 +03:00
zigc: test and fix strtol and similar
This commit is contained in:
+31
-21
@@ -158,29 +158,40 @@ fn stringToInteger(comptime T: type, noalias buf: [*:0]const u8, noalias maybe_e
|
||||
};
|
||||
|
||||
// The prefix is allowed iff base == 0 or base == base of the prefix
|
||||
const real_base: u6 = if (current[0] == '0') blk: {
|
||||
current += 1;
|
||||
const real_base: u6, const digits = blk: {
|
||||
if (current[0] == '0') {
|
||||
if ((base == 0 or base == 16) and std.ascii.toLower(current[1]) == 'x' and std.ascii.isHex(current[2])) {
|
||||
break :blk .{ 16, current[2..] };
|
||||
} else if (base == 0) {
|
||||
break :blk .{ 8, current };
|
||||
} else {
|
||||
break :blk .{
|
||||
switch (base) {
|
||||
0 => 10,
|
||||
else => @intCast(base),
|
||||
},
|
||||
current,
|
||||
};
|
||||
}
|
||||
} else {
|
||||
const real_base: u6 = switch (base) {
|
||||
0 => 10,
|
||||
else => @intCast(base),
|
||||
};
|
||||
|
||||
if ((base == 0 or base == 16) and std.ascii.toLower(current[0]) == 'x' and std.ascii.isHex(current[1])) {
|
||||
current += 1;
|
||||
break :blk 16;
|
||||
_ = std.fmt.charToDigit(current[0], real_base) catch {
|
||||
// No digits to parse. Setting errno to .INVAL is optional in this case.
|
||||
if (maybe_end) |end| {
|
||||
end.* = buf;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
break :blk .{ real_base, current };
|
||||
}
|
||||
|
||||
if ((base == 0 or base == 8) and std.ascii.isDigit(current[0])) {
|
||||
break :blk 8;
|
||||
}
|
||||
|
||||
break :blk switch (base) {
|
||||
0 => 10,
|
||||
else => @intCast(base),
|
||||
};
|
||||
} else switch (base) {
|
||||
0 => 10,
|
||||
else => @intCast(base),
|
||||
};
|
||||
|
||||
if (@typeInfo(T).int.signedness == .unsigned) {
|
||||
const result = parseDigitsWithSignGenericCharacter(T, u8, current, maybe_end, real_base, .pos) catch {
|
||||
const result = parseDigitsWithSignGenericCharacter(T, u8, digits, maybe_end, real_base, .pos) catch {
|
||||
std.c._errno().* = @intFromEnum(std.c.E.RANGE);
|
||||
return std.math.maxInt(T);
|
||||
};
|
||||
@@ -188,12 +199,12 @@ fn stringToInteger(comptime T: type, noalias buf: [*:0]const u8, noalias maybe_e
|
||||
return if (negative) -%result else result;
|
||||
}
|
||||
|
||||
if (negative) return parseDigitsWithSignGenericCharacter(T, u8, current, maybe_end, real_base, .neg) catch blk: {
|
||||
if (negative) return parseDigitsWithSignGenericCharacter(T, u8, digits, maybe_end, real_base, .neg) catch blk: {
|
||||
std.c._errno().* = @intFromEnum(std.c.E.RANGE);
|
||||
break :blk std.math.minInt(T);
|
||||
};
|
||||
|
||||
return parseDigitsWithSignGenericCharacter(T, u8, current, maybe_end, real_base, .pos) catch blk: {
|
||||
return parseDigitsWithSignGenericCharacter(T, u8, digits, maybe_end, real_base, .pos) catch blk: {
|
||||
std.c._errno().* = @intFromEnum(std.c.E.RANGE);
|
||||
break :blk std.math.maxInt(T);
|
||||
};
|
||||
@@ -222,7 +233,6 @@ fn parseDigitsWithSignGenericCharacter(
|
||||
var value: T = 0;
|
||||
while (true) {
|
||||
const c: u8 = std.math.cast(u8, current[0]) orelse break;
|
||||
if (!std.ascii.isAlphanumeric(c)) break;
|
||||
|
||||
const digit: u6 = @intCast(std.fmt.charToDigit(c, base) catch break);
|
||||
defer current += 1;
|
||||
|
||||
@@ -11166,6 +11166,13 @@ pub extern "c" fn atoi(str: [*:0]const c_char) c_int;
|
||||
pub extern "c" fn atol(str: [*:0]const c_char) c_long;
|
||||
pub extern "c" fn atoll(str: [*:0]const c_char) c_longlong;
|
||||
|
||||
pub extern "c" fn strtol(noalias str: [*:0]const c_char, noalias str_end: ?*[*:0]c_char, base: c_int) callconv(.c) c_long;
|
||||
pub extern "c" fn strtoll(noalias str: [*:0]const c_char, noalias str_end: ?*[*:0]c_char, base: c_int) callconv(.c) c_longlong;
|
||||
pub extern "c" fn strtoul(noalias str: [*:0]const c_char, noalias str_end: ?*[*:0]c_char, base: c_int) callconv(.c) c_ulong;
|
||||
pub extern "c" fn strtoull(noalias str: [*:0]const c_char, noalias str_end: ?*[*:0]c_char, base: c_int) callconv(.c) c_ulonglong;
|
||||
pub extern "c" fn strtoimax(noalias str: [*:0]const c_char, noalias str_end: ?*[*:0]c_char, base: c_int) callconv(.c) intmax_t;
|
||||
pub extern "c" fn strtoumax(noalias str: [*:0]const c_char, noalias str_end: ?*[*:0]c_char, base: c_int) callconv(.c) uintmax_t;
|
||||
|
||||
pub extern "c" fn bsearch(
|
||||
key: *const anyopaque,
|
||||
base: *const anyopaque,
|
||||
|
||||
Reference in New Issue
Block a user