Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions include/pup/core/string_id.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#pragma once

#include <compare>
#include <cstdint>

namespace pup {
Expand Down Expand Up @@ -36,10 +37,13 @@ constexpr auto make_string_id(std::uint32_t value) -> StringId
/// means: `handle_less` for a set, or a pool projection for anything observable.
/// The built-in enum comparison is interning order, and the two spellings were
/// indistinguishable — issues #171, #175, #183 and #184 were all that confusion.
/// <=> is deleted too, or a defaulted operator<=> on any struct holding a StringId
/// would order by handle without naming it.
auto operator<(StringId, StringId) -> bool = delete;
auto operator>(StringId, StringId) -> bool = delete;
auto operator<=(StringId, StringId) -> bool = delete;
auto operator>=(StringId, StringId) -> bool = delete;
auto operator<=>(StringId, StringId) -> std::strong_ordering = delete;

/// Order by interning handle. Valid only where the order is unobservable —
/// membership, dedup, binary search against a handle-keyed range.
Expand Down
6 changes: 5 additions & 1 deletion src/cli/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -460,14 +460,18 @@ auto compose_nested_project_subtree(std::string_view dir, ParseContext& ctx) ->
for (auto sub_id : sub_dirs) {
auto sub_sv = pool.get(sub_id);
auto rel_id = (sub_sv == ".") ? pool.intern(marker_prefix) : pup::path::join(marker_prefix, sub_sv);
if (!std::binary_search(available.begin(), available.end(), rel_id, pup::handle_less)) {
// Search only the sorted prefix: appending unsorts the tail, and a binary search
// over that reports a present directory absent, so it gets parsed twice.
auto* sorted_end = available.begin() + static_cast<std::ptrdiff_t>(before);
if (!std::binary_search(available.begin(), sorted_end, rel_id, pup::handle_less)) {
available.push_back(rel_id);
}
}
if (available.size() == before) {
return false;
}
std::sort(available.begin(), available.end(), pup::handle_less);
available.erase(std::unique(available.begin(), available.end()), available.end());
return true;
}

Expand Down
8 changes: 8 additions & 0 deletions src/exec/scheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,15 @@ auto prepare_job_launch(
for (auto var_id : base_env) {
env_ids.push_back(var_id);
}
// Handle order reaches the child: create_env_block (process-win32.cpp:102) emits this
// sequence verbatim, and Win32 expects an alphabetically sorted block.
auto exported = Vec<StringId> {};
for (auto var_id : job.exported_vars) {
exported.push_back(static_cast<StringId>(var_id));
}
std::ranges::sort(exported, {}, [&pool](StringId id) { return pool.get(id); });

for (auto var_id : exported) {
auto var_sv = pool.get(var_id);
if (auto it = env_cache_find(env_cache, var_sv)) {
auto eb = Buf {};
Expand Down
Loading