| author | |
| committer | |
| log | 815c8536f4e9e50e3ae58b191bd6d4bcd09f8796 |
| tree | 83e6efde5bb2283d899b6e56d058d095d214b366 |
| parent | 4ff17ef6c22c9a4fa7c4eb79ee4c46f5fb20cb56 |
3 files changed, 41 insertions(+), 1 deletions(-)
src/lib.zig+1| ... | @@ -118,3 +118,4 @@ pub usingnamespace @import("./compareFnBasic.zig"); | ... | @@ -118,3 +118,4 @@ pub usingnamespace @import("./compareFnBasic.zig"); |
| 118 | pub usingnamespace @import("./compareFnField.zig"); | 118 | pub usingnamespace @import("./compareFnField.zig"); |
| 119 | pub usingnamespace @import("./compareFnRange.zig"); | 119 | pub usingnamespace @import("./compareFnRange.zig"); |
| 120 | pub usingnamespace @import("./asciiLower.zig"); | 120 | pub usingnamespace @import("./asciiLower.zig"); |
| 121 | pub usingnamespace @import("./parseDigits.zig"); |
src/parseDigits.zig created+39| ... | @@ -0,0 +1,39 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const string = []const u8; | ||
| 3 | const extras = @import("./lib.zig"); | ||
| 4 | |||
| 5 | /// Simple number parser with no extra detection or handling. Alphabet is [0-9][a-z] with respect to base. | ||
| 6 | /// Partially motivated by https://codeberg.org/ziglang/zig/issues/30881 + https://github.com/ziglang/zig/issues/24687 | ||
| 7 | pub fn parseDigits(comptime T: type, buf: []const u8, base: u8) !T { | ||
| 8 | std.debug.assert(base > 0); | ||
| 9 | std.debug.assert(base <= 36); | ||
| 10 | if (buf.len == 0) return error.InvalidCharacter; | ||
| 11 | |||
| 12 | var result: T = 0; | ||
| 13 | for (0..buf.len) |i| { | ||
| 14 | const c = buf[buf.len - 1 - i]; | ||
| 15 | const d = switch (c) { | ||
| 16 | '0'...'9' => |a| a - '0', | ||
| 17 | 'a'...'z' => |a| a - 'a' + 10, | ||
| 18 | 'A'...'Z' => |a| a - 'A' + 10, | ||
| 19 | else => return error.InvalidCharacter, | ||
| 20 | }; | ||
| 21 | if (d == 0) continue; | ||
| 22 | if (d >= base) return error.Overflow; | ||
| 23 | const _x = if (i == 0) 1 else std.math.powi(T, @intCast(base), @intCast(i)) catch return error.Overflow; | ||
| 24 | const _y = try std.math.mul(T, @intCast(d), _x); | ||
| 25 | const _z = try std.math.add(T, result, _y); | ||
| 26 | result = _z; | ||
| 27 | } | ||
| 28 | return result; | ||
| 29 | } | ||
| 30 | |||
| 31 | test { | ||
| 32 | try std.testing.expect(try parseDigits(u8, "10", 10) == 10); | ||
| 33 | } | ||
| 34 | test { | ||
| 35 | try std.testing.expect(try parseDigits(u8, "20", 16) == 32); | ||
| 36 | } | ||
| 37 | test { | ||
| 38 | try std.testing.expect(try parseDigits(u8, "EF", 16) == 239); | ||
| 39 | } | ||
src/parse_int.zig+1-1| ... | @@ -4,7 +4,7 @@ const extras = @import("./lib.zig"); | ... | @@ -4,7 +4,7 @@ const extras = @import("./lib.zig"); |
| 4 | 4 | ||
| 5 | pub fn parse_int(comptime T: type, s: ?string, b: u8, d: T) T { | 5 | pub fn parse_int(comptime T: type, s: ?string, b: u8, d: T) T { |
| 6 | if (s == null) return d; | 6 | if (s == null) return d; |
| 7 | return std.fmt.parseInt(T, s.?, b) catch d; | 7 | return extras.parseDigits(T, s.?, b) catch d; |
| 8 | } | 8 | } |
| 9 | 9 | ||
| 10 | test { | 10 | test { |