// File: davmac314[P]dinit/src/includes/dinit-env.h
// Function: environment::build(dinit_unordered_set<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, hash_sv, dinit_equal_to> const&) const
env_map build(const env_names &exclude) const
    {
        env_map mapping;

        if (keep_parent_env) {
            // import all from parent, excluding our own undefines + the exclude set
            if (bp_sys::environ != nullptr) {
                unsigned pos = 0;
                for (char **env = bp_sys::environ; *env != nullptr; ++env) {
                    // find '='
                    char *var_ch;
                    for (var_ch = *env; *var_ch != '='; ++var_ch) {
                        if (*var_ch == '\0') break;
                    }
                    // if this variable doesn't contain '=', ignore it
                    if (*var_ch == '\0') continue;
                    string_view name_view {*env, (size_t)(var_ch - *env)};

                    if (undefine.contains(name_view) || exclude.contains(name_view)) {
                        goto next_env_var;
                    }

                    mapping.env_list.push_back(*env);
                    mapping.var_map.insert({name_view, pos});
                    ++pos;

                    next_env_var: ;
                }
            }
        }
        else {
            // import specific items from parent
            for (const std::string &import_name : import_from_parent) {
                // POSIX allows that getenv return its result in a static, per-thread buffer. Since this is
                // ridiculous, we'll assume that all implementations do the sane thing of simply returning
                // a pointer to the value part of the NAME=VALUE string in the actual environment array:
                const char *value = getenv(import_name.c_str());
                if (value == nullptr) continue;
                // go back through the name and the '=' to the beginning of NAME=VALUE:
                const char *name_and_val = value - (import_name.length() + 1);
                mapping.var_map.insert({import_name, mapping.env_list.size()});
                mapping.env_list.push_back(name_and_val);
            }
        }

        // add our own (excluding exclude set)
        for (const std::string &set_var : set_vars) {
            size_t eq_pos = set_var.find('=');
            string_view set_var_name = string_view(set_var.data(), eq_pos);

            if (!exclude.contains(set_var_name)) {
                auto iter = mapping.var_map.find(set_var_name);
                if (iter != mapping.var_map.end()) {
                    unsigned pos = iter->second;
                    mapping.env_list[pos] = set_var.c_str();
                }
                else {
                    mapping.var_map[set_var_name] = mapping.env_list.size();
                    mapping.env_list.push_back(set_var.c_str());
                }
            }
        }
        mapping.env_list.push_back(nullptr);

        return mapping;
    }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1f0, %rsp            # imm = 0x1F0
movq %rdi, -0x190(%rbp)
movq %rdi, %rax
movq %rax, -0x188(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x180(%rbp)
movb $0x0, -0x19(%rbp)
callq 0x1d210
movq -0x180(%rbp), %rax
testb $0x1, (%rax)
je 0x1ce6b
movq 0x3429d(%rip), %rax     # 0x50fa0
cmpq $0x0, (%rax)
je 0x1ce66
movl $0x0, -0x20(%rbp)
movq 0x34285(%rip), %rax     # 0x50fa0
movq (%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
cmpq $0x0, (%rax)
je 0x1ce64
movq -0x28(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x3d, %eax
je 0x1cd65
movq -0x30(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x0, %eax
jne 0x1cd55
jmp 0x1cd65
jmp 0x1cd57
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
jmp 0x1cd3b
movq -0x30(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x0, %eax
jne 0x1cd76
jmp 0x1ce36
movq -0x28(%rbp), %rax
movq (%rax), %rsi
movq -0x30(%rbp), %rdx
movq -0x28(%rbp), %rax
movq (%rax), %rax
subq %rax, %rdx
leaq -0x40(%rbp), %rdi
callq 0x15030
movq -0x180(%rbp), %rdi
addq $0x38, %rdi
leaq -0x40(%rbp), %rsi
callq 0x1d240
testb $0x1, %al
jne 0x1cdbf
movq -0x18(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x1d240
testb $0x1, %al
jne 0x1cdbf
jmp 0x1cdc1
jmp 0x1ce34
movq -0x190(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x18080
jmp 0x1cdd3
movq -0x190(%rbp), %rax
addq $0x18, %rax
movq %rax, -0x198(%rbp)
leaq -0x68(%rbp), %rdi
leaq -0x40(%rbp), %rsi
leaq -0x20(%rbp), %rdx
callq 0x1d2d0
jmp 0x1cdf8
movq -0x198(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x1d290
movb %dl, -0x1a1(%rbp)
movq %rax, -0x1a0(%rbp)
jmp 0x1ce17
movb -0x1a1(%rbp), %al
movq -0x1a0(%rbp), %rcx
movq %rcx, -0x78(%rbp)
movb %al, -0x70(%rbp)
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20(%rbp)
jmp 0x1ce36
movq -0x28(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x28(%rbp)
jmp 0x1cd22
movq -0x190(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
callq 0x16b40
jmp 0x1d1fb
jmp 0x1ce66
jmp 0x1cfd2
movq -0x180(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rsi
leaq -0x98(%rbp), %rdi
callq 0x1d310
movq -0x80(%rbp), %rsi
leaq -0xb0(%rbp), %rdi
callq 0x1d350
leaq -0x98(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
callq 0x1d390
testb $0x1, %al
jne 0x1ceb6
jmp 0x1cfd0
leaq -0x98(%rbp), %rdi
callq 0x1d3c0
movq %rax, -0xb8(%rbp)
movq -0xb8(%rbp), %rdi
callq 0x51b0
movq %rax, %rdi
callq 0x55f0
movq %rax, -0xc0(%rbp)
cmpq $0x0, -0xc0(%rbp)
jne 0x1cef3
jmp 0x1cfbf
movq -0xc0(%rbp), %rax
movq %rax, -0x1c0(%rbp)
movq -0xb8(%rbp), %rdi
callq 0x5770
movq -0x1c0(%rbp), %rcx
movq -0x190(%rbp), %rdi
notq %rax
addq %rcx, %rax
movq %rax, -0xc8(%rbp)
movq %rdi, %rax
addq $0x18, %rax
movq %rax, -0x1b8(%rbp)
movq -0xb8(%rbp), %rax
movq %rax, -0x1b0(%rbp)
callq 0x18560
movq -0x1b0(%rbp), %rsi
movq %rax, -0xe8(%rbp)
leaq -0xe0(%rbp), %rdi
leaq -0xe8(%rbp), %rdx
callq 0x1d3e0
jmp 0x1cf6c
movq -0x1b8(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
callq 0x1d290
movb %dl, -0x1c9(%rbp)
movq %rax, -0x1c8(%rbp)
jmp 0x1cf8e
movq -0x190(%rbp), %rdi
movb -0x1c9(%rbp), %al
movq -0x1c8(%rbp), %rcx
movq %rcx, -0xf8(%rbp)
movb %al, -0xf0(%rbp)
leaq -0xc8(%rbp), %rsi
callq 0x18080
jmp 0x1cfbd
jmp 0x1cfbf
leaq -0x98(%rbp), %rdi
callq 0x1d420
jmp 0x1ce9a
jmp 0x1cfd2
movq -0x180(%rbp), %rax
addq $0x68, %rax
movq %rax, -0x100(%rbp)
movq -0x100(%rbp), %rsi
leaq -0x118(%rbp), %rdi
callq 0x1d540
movq -0x100(%rbp), %rsi
leaq -0x130(%rbp), %rdi
callq 0x1d580
leaq -0x118(%rbp), %rdi
leaq -0x130(%rbp), %rsi
callq 0x1d5c0
testb $0x1, %al
jne 0x1d026
jmp 0x1d1b5
leaq -0x118(%rbp), %rdi
callq 0x1d5f0
movq %rax, -0x138(%rbp)
movq -0x138(%rbp), %rdi
movl $0x3d, %esi
xorl %eax, %eax
movl %eax, %edx
callq 0x5670
movq %rax, -0x140(%rbp)
movq -0x138(%rbp), %rdi
callq 0x5660
movq %rax, %rsi
movq -0x140(%rbp), %rdx
leaq -0x150(%rbp), %rdi
callq 0x15030
movq -0x18(%rbp), %rdi
leaq -0x150(%rbp), %rsi
callq 0x1d240
testb $0x1, %al
jne 0x1d1a2
movq -0x190(%rbp), %rdi
addq $0x18, %rdi
leaq -0x150(%rbp), %rsi
callq 0x1d610
movq %rax, -0x1d8(%rbp)
jmp 0x1d0af
movq -0x190(%rbp), %rdi
movq -0x1d8(%rbp), %rax
movq %rax, -0x158(%rbp)
addq $0x18, %rdi
callq 0x1d670
movq %rax, -0x160(%rbp)
leaq -0x158(%rbp), %rdi
leaq -0x160(%rbp), %rsi
callq 0x1d640
testb $0x1, %al
jne 0x1d0ed
jmp 0x1d135
leaq -0x158(%rbp), %rdi
callq 0x1d6a0
movl 0x10(%rax), %eax
movl %eax, -0x164(%rbp)
movq -0x138(%rbp), %rdi
callq 0x51b0
movq -0x190(%rbp), %rdi
movq %rax, -0x1e0(%rbp)
movl -0x164(%rbp), %eax
movl %eax, %esi
callq 0x1d6d0
movq -0x1e0(%rbp), %rcx
movq %rcx, (%rax)
jmp 0x1d1a0
movq -0x190(%rbp), %rdi
callq 0x18560
movq -0x190(%rbp), %rdi
movl %eax, -0x1ec(%rbp)
addq $0x18, %rdi
leaq -0x150(%rbp), %rsi
callq 0x1d6f0
movq %rax, -0x1e8(%rbp)
jmp 0x1d167
movq -0x1e8(%rbp), %rax
movl -0x1ec(%rbp), %ecx
movl %ecx, (%rax)
movq -0x138(%rbp), %rdi
callq 0x51b0
movq -0x190(%rbp), %rdi
movq %rax, -0x170(%rbp)
leaq -0x170(%rbp), %rsi
callq 0x1d720
jmp 0x1d19e
jmp 0x1d1a0
jmp 0x1d1a2
jmp 0x1d1a4
leaq -0x118(%rbp), %rdi
callq 0x1d750
jmp 0x1d00a
movq -0x190(%rbp), %rdi
movq $0x0, -0x178(%rbp)
leaq -0x178(%rbp), %rsi
callq 0x1d720
jmp 0x1d1d5
movb $0x1, -0x19(%rbp)
testb $0x1, -0x19(%rbp)
jne 0x1d1eb
movq -0x190(%rbp), %rdi
callq 0x16b40
movq -0x188(%rbp), %rax
addq $0x1f0, %rsp            # imm = 0x1F0
popq %rbp
retq
movq -0x48(%rbp), %rdi
callq 0x5870
nopw %cs:(%rax,%rax)
nop