Skip to content
StrPushBackMany

StrPushBackMany

Description

Append MANY characters to the end of str. R-form (the source bytes are read-only / borrowed). Two arities via MISRA_OVERLOAD:

StrPushBackMany(str, zstr) - 2 args; zstr is NUL-terminated. StrPushBackMany(str, cstr, cstr_len) - 3 args; counted view. (Zstr, size) adjacent.

No Fast variant: tail append is naturally O(1) amortised; the “Fast” semantics only matter for operations that would otherwise shift elements.

Success

Returns true; bytes copied at the tail.

Failure

Returns false on allocation failure. str unchanged.

Usage example (Cross-references)

Usage examples (Cross-references)
                char c2  = low < 10 ? '0' + low : is_caps ? 'A' + (low - 10) : 'a' + (low - 10);
    
                if (!StrPushBackMany(o, "\\x") || !StrPushBackR(o, c1) || !StrPushBackR(o, c2)) {
                    return false;
                }
                char c1  = hiw < 10 ? '0' + hiw : is_caps ? 'A' + (hiw - 10) : 'a' + (hiw - 10);
                char c2  = low < 10 ? '0' + low : is_caps ? 'A' + (low - 10) : 'a' + (low - 10);
                if (!StrPushBackMany(o, "\\x") || !StrPushBackR(o, c1) || !StrPushBackR(o, c2)) {
                    return false;
                }
            dot = ZstrFindChar(body, '.');
            if (!dot) {
                if (!StrPushBackMany(&result, body, ZstrLen(body))) {
                    goto fail;
                }
            frac   = (u64)ZstrLen(dot + 1);
    
            if (!StrPushBackMany(&result, body, prefix)) {
                goto fail;
            }
                    goto fail;
                }
                if (!StrPushBackMany(&result, dot + 1, MIN2(frac, (u64)precision))) {
                    goto fail;
                }
                        }
                    }
                    if (!StrPushBackMany(o, "0x") || !StrMerge(o, &hex)) {
                        StrDeinit(&hex);
                        return false;
                        } else {
                            Zstr digits = "0123456789abcdef";
                            if (!StrPushBackMany(o, "\\x") || !StrPushBackR(o, digits[(c >> 4) & 0xf]) ||
                                !StrPushBackR(o, digits[c & 0xf])) {
                                return false;
                        }
                    }
                    if (!StrPushBackMany(o, "0x") || !StrMerge(o, &hex)) {
                        StrDeinit(&hex);
                        return false;
                        } else {
                            Zstr digits = "0123456789abcdef";
                            if (!StrPushBackMany(o, "\\x") || !StrPushBackR(o, digits[(xs[i] >> 4) & 0xf]) ||
                                !StrPushBackR(o, digits[xs[i] & 0xf])) {
                                return false;
            // Direct string append for NaN
            if (fmt_info->flags & FMT_FLAG_CAPS) {
                if (!StrPushBackMany(o, "F64_NAN")) {
                    return false;
                }
                }
            } else {
                if (!StrPushBackMany(o, "nan")) {
                    return false;
                }
    
            if (fmt_info->flags & FMT_FLAG_CAPS) {
                if (!StrPushBackMany(o, "INF")) {
                    return false;
                }
                }
            } else {
                if (!StrPushBackMany(o, "inf")) {
                    return false;
                }
            // Format as hexadecimal
            if (bv->length == 0) {
                if (!StrPushBackMany(o, "0x0")) {
                    return false;
                }
            // Format as octal
            if (bv->length == 0) {
                if (!StrPushBackMany(o, "0o0")) {
                    return false;
                }
                Str *s = (Str *)target;
                StrClear(s);
                StrPushBackMany(s, value);
                return true;
            }
        Zstr src = sp->long_name;
        if (!src) {
            StrPushBackMany(out, "VALUE");
            return;
        }
    static u64 spec_format_left(const ArgSpec *sp, Str *out) {
        u64 start = out->length;
        StrPushBackMany(out, "  ");
        if (sp->role == ARG_ROLE_POSITIONAL) {
            StrPushBackR(out, '<');
        if (sp->role == ARG_ROLE_POSITIONAL) {
            StrPushBackR(out, '<');
            StrPushBackMany(out, sp->long_name);
            StrPushBackR(out, '>');
        } else {
        } else {
            if (sp->short_name) {
                StrPushBackMany(out, sp->short_name);
                if (sp->long_name)
                    StrPushBackMany(out, ", ");
                StrPushBackMany(out, sp->short_name);
                if (sp->long_name)
                    StrPushBackMany(out, ", ");
            } else {
                StrPushBackMany(out, "    ");
                    StrPushBackMany(out, ", ");
            } else {
                StrPushBackMany(out, "    ");
            }
            if (sp->long_name)
            }
            if (sp->long_name)
                StrPushBackMany(out, sp->long_name);
            if (sp->role == ARG_ROLE_REQUIRED || sp->role == ARG_ROLE_OPTIONAL) {
                StrPushBackR(out, ' ');
        // Usage line: "usage: name [OPTIONS] --req <REQ>... <POS>..."
        Str usage = StrInit(self->alloc);
        StrPushBackMany(&usage, "usage: ");
        StrPushBackMany(&usage, self->name);
        Str usage = StrInit(self->alloc);
        StrPushBackMany(&usage, "usage: ");
        StrPushBackMany(&usage, self->name);
    
        bool any_option = false;
        }
        if (any_option)
            StrPushBackMany(&usage, " [OPTIONS]");
    
        VecForeachPtr(&self->specs, sp) {
            StrPushBackR(&usage, ' ');
            if (sp->long_name)
                StrPushBackMany(&usage, sp->long_name);
            else if (sp->short_name)
                StrPushBackMany(&usage, sp->short_name);
                StrPushBackMany(&usage, sp->long_name);
            else if (sp->short_name)
                StrPushBackMany(&usage, sp->short_name);
            StrPushBackMany(&usage, " <");
            append_metavar(&usage, sp);
            else if (sp->short_name)
                StrPushBackMany(&usage, sp->short_name);
            StrPushBackMany(&usage, " <");
            append_metavar(&usage, sp);
            StrPushBackR(&usage, '>');
            if (sp->role != ARG_ROLE_POSITIONAL)
                continue;
            StrPushBackMany(&usage, " <");
            StrPushBackMany(&usage, sp->long_name);
            StrPushBackR(&usage, '>');
                continue;
            StrPushBackMany(&usage, " <");
            StrPushBackMany(&usage, sp->long_name);
            StrPushBackR(&usage, '>');
        }
                }
            } else {
                if (!StrPushBackMany(&result, "0.")) {
                    goto fail;
                }
        // (1) exact CodeView path
        *out_path = StrInit(out_path->allocator);
        StrPushBackMany(out_path, pe->codeview.pdb_path);
        if (path_exists(out_path->data))
            return true;
        if (out_path->length > 0)
            StrPushBackR(out_path, '/');
        StrPushBackMany(out_path, pdb_base);
        if (path_exists(out_path->data))
            return true;
        if (main->build_id && main->build_id_size > 0) {
            path.length = 0;
            StrPushBackMany(&path, "/usr/lib/debug/.build-id/");
            append_build_id_path(&path, main->build_id, main->build_id_size);
            StrPushBackMany(&path, ".debug");
            StrPushBackMany(&path, "/usr/lib/debug/.build-id/");
            append_build_id_path(&path, main->build_id, main->build_id_size);
            StrPushBackMany(&path, ".debug");
            if (path_exists(StrBegin(&path)) && ElfOpen(out, &path, alloc)) {
                if (sidecar_matches(main, out, /*by_build_id*/ true)) {
            append_dirname(&path, main_path);
            StrPushBackR(&path, '/');
            StrPushBackMany(&path, main->debuglink_name);
            if (path_exists(StrBegin(&path)) && ElfOpen(out, &path, alloc)) {
                if (sidecar_matches(main, out, /*by_build_id*/ false)) {
            path.length = 0;
            append_dirname(&path, main_path);
            StrPushBackMany(&path, "/.debug/");
            StrPushBackMany(&path, main->debuglink_name);
            if (path_exists(StrBegin(&path)) && ElfOpen(out, &path, alloc)) {
            append_dirname(&path, main_path);
            StrPushBackMany(&path, "/.debug/");
            StrPushBackMany(&path, main->debuglink_name);
            if (path_exists(StrBegin(&path)) && ElfOpen(out, &path, alloc)) {
                if (sidecar_matches(main, out, /*by_build_id*/ false)) {
            // (4) /usr/lib/debug{dir}/{name}
            path.length = 0;
            StrPushBackMany(&path, cand_prefix);
            append_dirname(&path, main_path);
            StrPushBackR(&path, '/');
            append_dirname(&path, main_path);
            StrPushBackR(&path, '/');
            StrPushBackMany(&path, main->debuglink_name);
            if (path_exists(StrBegin(&path)) && ElfOpen(out, &path, alloc)) {
                if (sidecar_matches(main, out, /*by_build_id*/ false)) {
    
        Str cmdline = StrInit(alloc);
        StrPushBackMany(&cmdline, filepath);
        for (char **arg = argv + 1; *arg; ++arg) {
            StrPushBackR(&cmdline, ' ');
        for (char **arg = argv + 1; *arg; ++arg) {
            StrPushBackR(&cmdline, ' ');
            StrPushBackMany(&cmdline, *arg);
        }
            return false;
        out->length = 0;
        StrPushBackMany(out, binary_path);
        StrPushBackMany(out, ".dSYM/Contents/Resources/DWARF/");
        StrPushBackMany(out, base);
        out->length = 0;
        StrPushBackMany(out, binary_path);
        StrPushBackMany(out, ".dSYM/Contents/Resources/DWARF/");
        StrPushBackMany(out, base);
        return true;
        StrPushBackMany(out, binary_path);
        StrPushBackMany(out, ".dSYM/Contents/Resources/DWARF/");
        StrPushBackMany(out, base);
        return true;
    }
                // the longest reasonable IPv6-with-zone-id literal.
                StrInitStack(ip_buf, 64) {
                    StrPushBackMany(&ip_buf, (Zstr)(si.data + ip_start), ip_len);
                    got_v4 = parse_ipv4(StrBegin(&ip_buf), v4);
                    if (!got_v4) {
                if (ip_len > 0 && ip_len < 64) {
                    StrInitStack(ip_buf, 64) {
                        StrPushBackMany(&ip_buf, (Zstr)(si.data + ip_start), ip_len);
                        u8 v4[4]  = {0};
                        u8 v6[16] = {0};
        bool ok = false;
        StrInitStack(host, 256) {
            StrPushBackMany(&host, spec, colon_at);
            ok = dns_resolve_5_zstr(self, StrBegin(&host), port, kind, out);
        }
            (void)alloc;
            Str raw = StrInit(scope);
            StrPushBackMany(&raw, prefix_bytes);
    
            HttpRequest req = HttpRequestInit(scope);
    
        // Add some data
        StrPushBackMany(&s, "Hello");
    
        // Original capacity should be at least 100
    // Test StrPushBackMany function
    bool test_str_push_back_cstr(void) {
        WriteFmt("Testing StrPushBackMany\n");
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        // Push a string at the back
        StrPushBackMany(&s, " World", 6);
    
        // Check that the string was inserted correctly
    // Test StrPushBackMany function
    bool test_str_push_back_zstr(void) {
        WriteFmt("Testing StrPushBackMany\n");
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        // Push a string at the back
        StrPushBackMany(&s, " World");
    
        // Check that the string was inserted correctly
        // StrInitStack declares and scopes `stack_str` itself (for-chain idiom).
        StrInitStack(stack_str, 20) {
            StrPushBackMany(&stack_str, "Hello, Stack!");
            ValidateStr(&stack_str);
Last updated on