tiny.profiling.substitute
Defined in tiny.profiling.
API (2)
Actions
Public operations.
Types and contracts
Public types and contracts.
Source
Source: src/profiling/root.zig:43
zig
pub const substitute = @import("substitute.zig");Source: src/profiling/substitute.zig
zig
const std = @import("std");pub const Replacement = struct { token: []const u8, value: []const u8,};pub fn resolve( allocator: std.mem.Allocator, template: []const u8, replacements: []const Replacement, maximum_bytes: usize,) ![]const u8 { if (maximum_bytes == 0 or std.mem.indexOfScalar(u8, template, 0) != null) { return error.InvalidResolvedString; } for (replacements) |replacement| { if (replacement.token.len == 0 or std.mem.indexOfScalar(u8, replacement.token, 0) != null or std.mem.indexOfScalar(u8, replacement.value, 0) != null) { return error.InvalidResolvedString; } } if (template.len > maximum_bytes) return error.InvalidResolvedString; var result = template; var owned: ?[]u8 = null; errdefer if (owned) |bytes| allocator.free(bytes); for (replacements) |replacement| { const next = try replace( allocator, result, replacement, maximum_bytes, ) orelse continue; if (owned) |bytes| allocator.free(bytes); result = next; owned = next; } return result;}fn replace( allocator: std.mem.Allocator, input: []const u8, replacement: Replacement, maximum_bytes: usize,) !?[]u8 { const count = std.mem.count(u8, input, replacement.token); if (count == 0) return null; const removed = std.math.mul(usize, count, replacement.token.len) catch return error.InvalidResolvedString; const added = std.math.mul(usize, count, replacement.value.len) catch return error.InvalidResolvedString; const base = input.len - removed; const resolved_bytes = std.math.add(usize, base, added) catch return error.InvalidResolvedString; if (resolved_bytes > maximum_bytes) return error.InvalidResolvedString; const result = try allocator.alloc(u8, resolved_bytes); _ = std.mem.replace( u8, input, replacement.token, replacement.value, result, ); return result;}test "profiling substitutions resolve bounded repeated tokens once" { var arena_state = std.heap.ArenaAllocator.init(std.testing.allocator); defer arena_state.deinit(); const allocator = arena_state.allocator(); const result = try resolve(allocator, "{root}/{side}/{root}", &.{ .{ .token = "{root}", .value = "/tmp/{side}" }, .{ .token = "{side}", .value = "candidate" }, }, 128); try std.testing.expectEqualStrings( "/tmp/candidate/candidate//tmp/candidate", result, ); try std.testing.expectEqualStrings( "literal", try resolve(allocator, "literal", &.{}, 7), ); try std.testing.expectEqualStrings( "", try resolve(allocator, "", &.{}, 1), ); try std.testing.expectEqualStrings( "12345678", try resolve(allocator, "{value}", &.{.{ .token = "{value}", .value = "12345678", }}, 8), ); try std.testing.expectError( error.InvalidResolvedString, resolve(allocator, "{value}", &.{.{ .token = "{value}", .value = "123456789", }}, 8), );}Audit
| Definitions | 3 |
|---|---|
| Public names | 3 |
| Members | 2 |
| Version | 26.7.0 |
| Revision | daab053ee433 |