StrPushBackMany
Description
Append MANY characters to the end of str. R-form (the source bytes are read-only / borrowed). Two arities via 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)
- In
ArgParse.c:137:
Str *s = (Str *)target;
StrClear(s);
StrPushBackMany(s, value);
return true;
}- In
ArgParse.c:269:
Zstr src = sp->long_name;
if (!src) {
StrPushBackMany(out, "VALUE");
return;
}- In
ArgParse.c:289:
static u64 spec_format_left(const ArgSpec *sp, Str *out) {
u64 start = StrLen(out);
StrPushBackMany(out, " ");
if (sp->role == ARG_ROLE_POSITIONAL) {
StrPushBackR(out, '<');- In
ArgParse.c:292:
if (sp->role == ARG_ROLE_POSITIONAL) {
StrPushBackR(out, '<');
StrPushBackMany(out, sp->long_name);
StrPushBackR(out, '>');
} else {- In
ArgParse.c:296:
} else {
if (sp->short_name) {
StrPushBackMany(out, sp->short_name);
if (sp->long_name)
StrPushBackMany(out, ", ");- In
ArgParse.c:298:
StrPushBackMany(out, sp->short_name);
if (sp->long_name)
StrPushBackMany(out, ", ");
} else {
StrPushBackMany(out, " ");- In
ArgParse.c:300:
StrPushBackMany(out, ", ");
} else {
StrPushBackMany(out, " ");
}
if (sp->long_name)- In
ArgParse.c:303:
}
if (sp->long_name)
StrPushBackMany(out, sp->long_name);
if (sp->role == ARG_ROLE_REQUIRED || sp->role == ARG_ROLE_OPTIONAL) {
StrPushBackR(out, ' ');- In
ArgParse.c:327:
// Usage line: "usage: name [OPTIONS] --req <REQ>... <POS>..."
Str usage = StrInit(self->alloc);
StrPushBackMany(&usage, "usage: ");
StrPushBackMany(&usage, self->name);- In
ArgParse.c:328:
Str usage = StrInit(self->alloc);
StrPushBackMany(&usage, "usage: ");
StrPushBackMany(&usage, self->name);
bool any_option = false;- In
ArgParse.c:338:
}
if (any_option)
StrPushBackMany(&usage, " [OPTIONS]");
VecForeachPtr(&self->specs, sp) {- In
ArgParse.c:345:
StrPushBackR(&usage, ' ');
if (sp->long_name)
StrPushBackMany(&usage, sp->long_name);
else if (sp->short_name)
StrPushBackMany(&usage, sp->short_name);- In
ArgParse.c:347:
StrPushBackMany(&usage, sp->long_name);
else if (sp->short_name)
StrPushBackMany(&usage, sp->short_name);
StrPushBackMany(&usage, " <");
append_metavar(&usage, sp);- In
ArgParse.c:348:
else if (sp->short_name)
StrPushBackMany(&usage, sp->short_name);
StrPushBackMany(&usage, " <");
append_metavar(&usage, sp);
StrPushBackR(&usage, '>');- In
ArgParse.c:355:
if (sp->role != ARG_ROLE_POSITIONAL)
continue;
StrPushBackMany(&usage, " <");
StrPushBackMany(&usage, sp->long_name);
StrPushBackR(&usage, '>');- In
ArgParse.c:356:
continue;
StrPushBackMany(&usage, " <");
StrPushBackMany(&usage, sp->long_name);
StrPushBackR(&usage, '>');
}- In
Io.c:1228:
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;
}- In
Io.c:1265:
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;
}- In
Io.c:1398:
dot = ZstrFindChar(body, '.');
if (!dot) {
if (!StrPushBackMany(&result, body, ZstrLen(body))) {
goto fail;
}- In
Io.c:1421:
frac = (u64)ZstrLen(dot + 1);
if (!StrPushBackMany(&result, body, prefix)) {
goto fail;
}- In
Io.c:1428:
goto fail;
}
if (!StrPushBackMany(&result, dot + 1, MIN2(frac, (u64)precision))) {
goto fail;
}- In
Io.c:1792:
}
}
if (!StrPushBackMany(o, "0x") || !StrMergeR(o, &hex)) {
return false;
}- In
Io.c:1822:
} else {
Zstr digits = "0123456789abcdef";
if (!StrPushBackMany(o, "\\x") || !StrPushBackR(o, digits[(c >> 4) & 0xf]) ||
!StrPushBackR(o, digits[c & 0xf])) {
return false;- In
Io.c:1879:
}
}
if (!StrPushBackMany(o, "0x") || !StrMergeR(o, &hex)) {
return false;
}- In
Io.c:1909:
} else {
Zstr digits = "0123456789abcdef";
if (!StrPushBackMany(o, "\\x") || !StrPushBackR(o, digits[(xs[i] >> 4) & 0xf]) ||
!StrPushBackR(o, digits[xs[i] & 0xf])) {
return false;- In
Io.c:2161:
if (F64IsNan(*v)) {
if (fmt_info->flags & FMT_FLAG_CAPS) {
if (!StrPushBackMany(o, "F64_NAN")) {
return false;
}- In
Io.c:2165:
}
} else {
if (!StrPushBackMany(o, "nan")) {
return false;
}- In
Io.c:2177:
if (fmt_info->flags & FMT_FLAG_CAPS) {
if (!StrPushBackMany(o, "INF")) {
return false;
}- In
Io.c:2181:
}
} else {
if (!StrPushBackMany(o, "inf")) {
return false;
}- In
Io.c:3055:
// Render "0x0" / "0o0" placeholders for the zero-length
// edge case so the prefix is visible even with no bits.
if (!StrPushBackMany(o, "0x0")) {
return false;
}- In
Io.c:3070:
} else if (fmt_info->flags & FMT_FLAG_OCTAL) {
if (BitVecLen(bv) == 0) {
if (!StrPushBackMany(o, "0o0")) {
return false;
}- In
Float.c:693:
}
} else {
if (!StrPushBackMany(&result, "0.")) {
goto fail;
} if (main->build_id && main->build_id_size > 0) {
StrResize(&path, 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 (sys_path_exists(StrBegin(&path)) && ElfOpen(out, &path, alloc)) {
if (sidecar_matches(main, out, /*by_build_id*/ true)) { sys_append_dirname(&path, main_path);
StrPushBackR(&path, '/');
StrPushBackMany(&path, main->debuglink_name);
if (sys_path_exists(StrBegin(&path)) && ElfOpen(out, &path, alloc)) {
if (sidecar_matches(main, out, /*by_build_id*/ false)) { StrResize(&path, 0);
sys_append_dirname(&path, main_path);
StrPushBackMany(&path, "/.debug/");
StrPushBackMany(&path, main->debuglink_name);
if (sys_path_exists(StrBegin(&path)) && ElfOpen(out, &path, alloc)) { sys_append_dirname(&path, main_path);
StrPushBackMany(&path, "/.debug/");
StrPushBackMany(&path, main->debuglink_name);
if (sys_path_exists(StrBegin(&path)) && ElfOpen(out, &path, alloc)) {
if (sidecar_matches(main, out, /*by_build_id*/ false)) { // (4) /usr/lib/debug{dir}/{name}
StrResize(&path, 0);
StrPushBackMany(&path, cand_prefix);
sys_append_dirname(&path, main_path);
StrPushBackR(&path, '/'); sys_append_dirname(&path, main_path);
StrPushBackR(&path, '/');
StrPushBackMany(&path, main->debuglink_name);
if (sys_path_exists(StrBegin(&path)) && ElfOpen(out, &path, alloc)) {
if (sidecar_matches(main, out, /*by_build_id*/ false)) {- In
PdbCache.c:37:
// (1) exact CodeView path
*out_path = StrInit(StrAllocator(out_path));
StrPushBackMany(out_path, cv->pdb_path);
if (sys_path_exists(StrBegin(out_path)))
return true;- In
PdbCache.c:50:
if (StrLen(out_path) > 0)
StrPushBackR(out_path, '/');
StrPushBackMany(out_path, pdb_base);
if (sys_path_exists(StrBegin(out_path)))
return true;- In
Dns.c:188:
// the longest reasonable IPv6-with-zone-id literal.
StrInitStack(ip_buf, 64) {
StrPushBackMany(&ip_buf, (Zstr)StrIterDataAt(&si, ip_start), ip_len);
got_v4 = parse_ipv4(StrBegin(&ip_buf), v4);
if (!got_v4) {- In
Dns.c:286:
if (ip_len > 0 && ip_len < 64) {
StrInitStack(ip_buf, 64) {
StrPushBackMany(&ip_buf, (Zstr)StrIterDataAt(&si, ip_start), ip_len);
u8 v4[4] = {0};
u8 v6[16] = {0};- In
Dns.c:344:
return false;
Str buf = StrInit(self->allocator);
StrPushBackMany(&buf, path, len);
bool ok = dns_add_path(self, StrBegin(&buf), do_hosts, do_resolv);
StrDeinit(&buf);- In
Dns.c:684:
bool ok = false;
StrInitStack(host, 256) {
StrPushBackMany(&host, spec, colon_at);
ok = dns_resolve_5_zstr(self, StrBegin(&host), port, kind, out);
}- In
MachoCache.c:29:
return false;
StrResize(out, 0);
StrPushBackMany(out, binary_path);
StrPushBackMany(out, ".dSYM/Contents/Resources/DWARF/");
StrPushBackMany(out, base);- In
MachoCache.c:30:
StrResize(out, 0);
StrPushBackMany(out, binary_path);
StrPushBackMany(out, ".dSYM/Contents/Resources/DWARF/");
StrPushBackMany(out, base);
return true;- In
MachoCache.c:31:
StrPushBackMany(out, binary_path);
StrPushBackMany(out, ".dSYM/Contents/Resources/DWARF/");
StrPushBackMany(out, base);
return true;
}- In
Proc.c:225:
Str cmdline = StrInit(alloc);
StrPushBackMany(&cmdline, filepath);
for (char **arg = argv + 1; *arg; ++arg) {
StrPushBackR(&cmdline, ' ');- In
Proc.c:228:
for (char **arg = argv + 1; *arg; ++arg) {
StrPushBackR(&cmdline, ' ');
StrPushBackMany(&cmdline, *arg);
}- In
Pdb.c:506:
static bool pool_append_cstr(Str *pool, Zstr s, u64 *out_offset) {
*out_offset = StrLen(pool);
if (!StrPushBackMany(pool, s))
return false;
return StrPushBackR(pool, '\0');- In
Http.c:488:
if (StrLen(&response->body)) {
if (!StrPushBackMany(&out, StrBegin(&response->body), StrLen(&response->body))) {
LOG_ERROR("HttpResponseSerialize: failed to append body");
StrDeinit(&out);- In
Dwarf.c:55:
static bool pool_append(Str *pool, Zstr s, u64 *out_offset) {
u64 start = StrLen(pool);
if (!StrPushBackMany(pool, s))
return false;
if (!StrPushBackR(pool, '\0'))- In
Beam.c:250:
Scope(scope, DefaultAllocator) {
Str raw = StrInit(scope);
StrPushBackMany(&raw, prefix_bytes);
HttpRequest req = HttpRequestInit(scope);- In
ArgParse.c:1150:
ArgParse p = ArgParseInit("prog", NULL, &a);
Str name = StrInit(&a);
StrPushBackMany(&name, "stale");
ArgOptional(&p, NULL, "--name", &name, "n");
char *argv[] = {(char *)"prog", (char *)"--name", (char *)"bob"};- In
Write.c:2909:
bool ok = true;
StrPushBackMany(&output, "XYZ");
f64 v = 1.5;- In
Memory.c:29:
// Add some data
StrPushBackMany(&s, "Hello");
// Original capacity should be at least 100
- In
Init.c:176:
// StrInitStack declares and scopes `stack_str` itself (for-chain idiom).
StrInitStack(stack_str, 20) {
StrPushBackMany(&stack_str, "Hello, Stack!");
ValidateStr(&stack_str);- In
Insert.c:137:
// Test StrPushBackMany function
bool test_str_push_back_cstr(void) {
WriteFmt("Testing StrPushBackMany\n");
DefaultAllocator alloc = DefaultAllocatorInit();- In
Insert.c:144:
// Push a string at the back
StrPushBackMany(&s, " World", 6);
// Check that the string was inserted correctly
- In
Insert.c:156:
// Test StrPushBackMany function
bool test_str_push_back_zstr(void) {
WriteFmt("Testing StrPushBackMany\n");
DefaultAllocator alloc = DefaultAllocatorInit();- In
Insert.c:163:
// Push a string at the back
StrPushBackMany(&s, " World");
// Check that the string was inserted correctly
- In
PdbCache.c:651:
const u64 mbase = 0x140000000ull;
StrInitStack(mod, 1100) {
StrPushBackMany(&mod, (Zstr)pe_path);
Zstr name = NULL;
u32 off = 0;- In
SysDns.c:738:
u64 padlen = ZstrLen(pad);
for (int i = 0; i < 300; ++i) {
StrPushBackMany(&body, pad, padlen);
}
StrPushBackMany(&body, "10.20.30.40 farhost\n", ZstrLen("10.20.30.40 farhost\n"));- In
SysDns.c:740:
StrPushBackMany(&body, pad, padlen);
}
StrPushBackMany(&body, "10.20.30.40 farhost\n", ZstrLen("10.20.30.40 farhost\n"));
DnsResolver r;- In
SysDns.c:1297:
Str smeared = StrInitFromStr(&path, a);
StrPushBackMany(&smeared, "ZZZ", 3);
bool added = DnsResolverAddHostsPath(&r, StrBegin(&smeared), plen);- In
MachoCache.c:868:
Str mod = StrInit(base);
StrPushBackMany(&mod, bin_path);
Zstr name = NULL;
Last updated on