╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ process_headers.zig ──────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭ find file ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╮ ╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │ │ │http│ ssh │ │ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╯ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
354 }); 355 try Dir.cwd().createDirPath(io, out_dir); 356 357 var missed_opportunity_bytes: usize = 0; 358 // iterate path_table. for each path, put all the hashes into a list. sort by hit_count. 359 // the hash with the highest hit_count gets to be the "generic" one. everybody else 360 // gets their header in a separate arch directory. 361 var path_it = path_table.iterator(); 362 while (path_it.next()) |path_kv| { 363 var contents_list = std.array_list.Managed(*Contents).init(arena); 364 { 365 var hash_it = path_kv.value_ptr.*.iterator(); 366 while (hash_it.next()) |hash_kv| { 367 const contents = hash_to_contents.getPtr(hash_kv.value_ptr.*).?; 368 try contents_list.append(contents); 369 } 370 } 371 std.mem.sort(*Contents, contents_list.items, {}, Contents.hitCountLessThan); 372 const best_contents = contents_list.pop().?; 373 if (best_contents.hit_count > 1) { 374 // worth it to make it generic 375 const full_path = try Dir.path.join(arena, &[_][]const u8{ out_dir, generic_name, path_kv.key_ptr.* }); 376 try Dir.cwd().createDirPath(io, Dir.path.dirname(full_path).?); 377 try Dir.cwd().writeFile(io, .{ .sub_path = full_path, .data = best_contents.bytes }); 378 best_contents.is_generic = true; 379 while (contents_list.pop()) |contender| { 380 if (contender.hit_count > 1) { 381 const this_missed_bytes = contender.hit_count * contender.bytes.len; 382 missed_opportunity_bytes += this_missed_bytes; 383 std.debug.print("Missed opportunity ({B}): {s}\n", .{ 384 this_missed_bytes, 385 path_kv.key_ptr.*, 386 }); 387 } else break; 388 } 389 } 390 var hash_it = path_kv.value_ptr.*.iterator(); 391 while (hash_it.next()) |hash_kv| { 392 const contents = hash_to_contents.get(hash_kv.value_ptr.*).?; 393 if (contents.is_generic) continue; 394 395 const dest_target = hash_kv.key_ptr.*; 396 const full_path = try Dir.path.join(arena, &[_][]const u8{ out_dir, dest_target, path_kv.key_ptr.* }); 397 try Dir.cwd().createDirPath(io, Dir.path.dirname(full_path).?); 398 try Dir.cwd().writeFile(io, .{ .sub_path = full_path, .data = contents.bytes }); 399 } 400 } 401 } 402 403 fn usageAndExit(arg0: []const u8) noreturn { 404 std.debug.print("Usage: {s} [--search-path <dir>] --out <dir> --abi <name>\n", .{arg0}); 405 std.debug.print("--search-path can be used any number of times.\n", .{}); 406 std.debug.print(" subdirectories of search paths look like, e.g. x86_64-linux-gnu\n", .{}); 407 std.debug.print("--out is a dir that will be created, and populated with the results\n", .{}); 408 std.debug.print("--abi is either glibc, musl, freebsd, netbsd, or openbsd\n", .{}); 409 std.process.exit(1); 410 } 411