ZstrFindSubstring
Description
Find first occurrence of needle in haystack.
Success
Returns pointer to first occurrence or NULL if not found.
Failure
Aborts via LOG_FATAL when either pointer is NULL.
Usage example (Cross-references)
Usage examples (Cross-references)
- In
Zstr.c:331:
}
Zstr ZstrFindSubstring(Zstr haystack, Zstr needle) {
if (!needle) {
LOG_FATAL("Invalid arguments");- In
Str.c:246:
Zstr str_find_zstr(const Str *s, Zstr key) {
ValidateStr(s);
return ZstrFindSubstring(StrBegin(s), key);
}- In
BitVec.c:1917:
bool result = false;
if (ZstrFindSubstring(StrBegin(&bv_str), pattern) != NULL) {
result = true;
}- In
AllocDebug.c:128:
bool ok = StrLen(&out) > 0;
ok = ok && (ZstrFindSubstring(StrBegin(&out), "leak:") != NULL);
ok = ok && (ZstrFindSubstring(StrBegin(&out), "24 bytes") != NULL);
ok = ok && (ZstrFindSubstring(StrBegin(&out), "40 bytes") != NULL);- In
AllocDebug.c:129:
bool ok = StrLen(&out) > 0;
ok = ok && (ZstrFindSubstring(StrBegin(&out), "leak:") != NULL);
ok = ok && (ZstrFindSubstring(StrBegin(&out), "24 bytes") != NULL);
ok = ok && (ZstrFindSubstring(StrBegin(&out), "40 bytes") != NULL);- In
AllocDebug.c:130:
ok = ok && (ZstrFindSubstring(StrBegin(&out), "leak:") != NULL);
ok = ok && (ZstrFindSubstring(StrBegin(&out), "24 bytes") != NULL);
ok = ok && (ZstrFindSubstring(StrBegin(&out), "40 bytes") != NULL);
StrDeinit(&out); DebugAllocatorReportLeaks(&dbg, &out);
bool ok = (ZstrFindSubstring(StrBegin(&out), "leak:") != NULL);
// FormatStackTrace renders frame lines beginning with "#0".
ok = ok && (ZstrFindSubstring(StrBegin(&out), "#0") != NULL); bool ok = (ZstrFindSubstring(StrBegin(&out), "leak:") != NULL);
// FormatStackTrace renders frame lines beginning with "#0".
ok = ok && (ZstrFindSubstring(StrBegin(&out), "#0") != NULL);
StrDeinit(&out); DebugAllocatorReportLeaks(&dbg, &out);
ok = ok && (ZstrFindSubstring(StrBegin(&out), "leak:") != NULL);
// Real emits "#0" and "#1"; the `--i` mutant emits only "#0".
ok = ok && (ZstrFindSubstring(StrBegin(&out), "#0 ") != NULL); ok = ok && (ZstrFindSubstring(StrBegin(&out), "leak:") != NULL);
// Real emits "#0" and "#1"; the `--i` mutant emits only "#0".
ok = ok && (ZstrFindSubstring(StrBegin(&out), "#0 ") != NULL);
ok = ok && (ZstrFindSubstring(StrBegin(&out), "#1 ") != NULL); // Real emits "#0" and "#1"; the `--i` mutant emits only "#0".
ok = ok && (ZstrFindSubstring(StrBegin(&out), "#0 ") != NULL);
ok = ok && (ZstrFindSubstring(StrBegin(&out), "#1 ") != NULL);
StrDeinit(&out); StrAppendFmt(&ns, "#{} ", n);
ok = ok && (ZstrFindSubstring(StrBegin(&out), "leak:") != NULL);
// The valid top frame "#(N-1) " is present; the spurious "#N " is not.
ok = ok && (ZstrFindSubstring(StrBegin(&out), StrBegin(&ns)) == NULL); ok = ok && (ZstrFindSubstring(StrBegin(&out), "leak:") != NULL);
// The valid top frame "#(N-1) " is present; the spurious "#N " is not.
ok = ok && (ZstrFindSubstring(StrBegin(&out), StrBegin(&ns)) == NULL);
StrDeinit(&ns);- In
ArgParse.c:855:
// opt50 is inside the 64-row window (rendered); opt64 is past it.
bool ok = ZstrFindSubstring(StrBegin(&out), "--opt50") != NULL &&
ZstrFindSubstring(StrBegin(&out), "--opt00") != NULL &&
ZstrFindSubstring(StrBegin(&out), "--opt64") == NULL;- In
ArgParse.c:856:
// opt50 is inside the 64-row window (rendered); opt64 is past it.
bool ok = ZstrFindSubstring(StrBegin(&out), "--opt50") != NULL &&
ZstrFindSubstring(StrBegin(&out), "--opt00") != NULL &&
ZstrFindSubstring(StrBegin(&out), "--opt64") == NULL;
if (!ok) {- In
ArgParse.c:857:
bool ok = ZstrFindSubstring(StrBegin(&out), "--opt50") != NULL &&
ZstrFindSubstring(StrBegin(&out), "--opt00") != NULL &&
ZstrFindSubstring(StrBegin(&out), "--opt64") == NULL;
if (!ok) {
WriteFmt("[a1] render cap: window wrong\n{}\n", StrBegin(&out));- In
Backtrace.c:41:
// (Apple's C mangling prepends `_`; substring search matches both
// "bt_capture_with_helper" and "_bt_capture_with_helper".)
bool ok = StrLen(&rendered) > 0 && ZstrFindSubstring(StrBegin(&rendered), "bt_capture_with_helper") != NULL &&
ZstrFindSubstring(StrBegin(&rendered), "bt_capture_outer") != NULL;- In
Backtrace.c:42:
// "bt_capture_with_helper" and "_bt_capture_with_helper".)
bool ok = StrLen(&rendered) > 0 && ZstrFindSubstring(StrBegin(&rendered), "bt_capture_with_helper") != NULL &&
ZstrFindSubstring(StrBegin(&rendered), "bt_capture_outer") != NULL;
#if FEATURE_SYS_SYMRESOLVE- In
Backtrace.c:48:
// the Linux backend emits source filenames today (via DwarfLines);
// macOS / Windows only emit names + offsets.
ok = ok && ZstrFindSubstring(StrBegin(&rendered), "Backtrace.c") != NULL;
#endif- In
Backtrace.c:81:
ok = ok && StrLen(&rendered) > 0;
ok = ok && ZstrFindSubstring(StrBegin(&rendered), "bt_vec_capture_with_helper") != NULL;
ok = ok && ZstrFindSubstring(StrBegin(&rendered), "bt_vec_capture_outer") != NULL;- In
Backtrace.c:82:
ok = ok && StrLen(&rendered) > 0;
ok = ok && ZstrFindSubstring(StrBegin(&rendered), "bt_vec_capture_with_helper") != NULL;
ok = ok && ZstrFindSubstring(StrBegin(&rendered), "bt_vec_capture_outer") != NULL;
StrDeinit(&rendered);- In
Backtrace.c:111:
// Should also contain the helper name through the shared resolver.
bool ok = StrLen(&out) > 0 && ZstrFindSubstring(StrBegin(&out), "bt_capture_with_helper") != NULL;
StrDeinit(&out);- In
Backtrace.c:154:
bool ok = n >= 2;
ok = ok && StrLen(&rendered) > 0;
ok = ok && ZstrFindSubstring(StrBegin(&rendered), "cfi_capture_inner") != NULL;
ok = ok && ZstrFindSubstring(StrBegin(&rendered), "cfi_capture_outer") != NULL;- In
Backtrace.c:155:
ok = ok && StrLen(&rendered) > 0;
ok = ok && ZstrFindSubstring(StrBegin(&rendered), "cfi_capture_inner") != NULL;
ok = ok && ZstrFindSubstring(StrBegin(&rendered), "cfi_capture_outer") != NULL;
StrDeinit(&rendered); ok = ok && r.module_path && r.module_path[0] != '\0';
ok = ok && r.symbol_name != NULL;
ok = ok && ZstrFindSubstring(r.symbol_name, "sr1_marker_a") != NULL;
SymbolResolverDeinit(&res); ok = ok && resolve_addr(&res, (void *)&sr1_marker_b, &rb);
ok = ok && ra.symbol_name && rb.symbol_name;
ok = ok && ZstrFindSubstring(ra.symbol_name, "sr1_marker_a") != NULL;
ok = ok && ZstrFindSubstring(rb.symbol_name, "sr1_marker_b") != NULL;
ok = ok && ra.symbol_value != rb.symbol_value; ok = ok && ra.symbol_name && rb.symbol_name;
ok = ok && ZstrFindSubstring(ra.symbol_name, "sr1_marker_a") != NULL;
ok = ok && ZstrFindSubstring(rb.symbol_name, "sr1_marker_b") != NULL;
ok = ok && ra.symbol_value != rb.symbol_value; ResolvedSymbol r;
bool ok = SymbolResolverResolve(&res, (void *)&symres_marker_helper, &r);
ok = ok && r.symbol_name != NULL && ZstrFindSubstring(r.symbol_name, "symres_marker_helper") != NULL;
SymbolResolverDeinit(&res); ResolvedSymbol r;
bool ok = SymbolResolverResolve(&res, (void *)&sr_notype_marker, &r);
ok = ok && r.symbol_name && ZstrFindSubstring(r.symbol_name, "sr_notype_marker") != NULL;
// size-0 symbol: it matched at its exact value, so the offset is zero.
ok = ok && r.offset == 0; ResolvedSymbol r;
bool ok = SymbolResolverResolve(&res, (void *)&sr_cache_data_marker, &r);
ok = ok && r.symbol_name && ZstrFindSubstring(r.symbol_name, "sr_cache_data_marker") != NULL;
SymbolResolverDeinit(&res);- In
SymBind.c:61:
bool ok = SymbolResolverResolve(&res, (void *)&sr_bind_global_sized, &r);
ok = ok && r.symbol_name != NULL;
ok = ok && ZstrFindSubstring(r.symbol_name, "sr_bind_global_sized") != NULL;
ok = ok && ZstrFindSubstring(r.symbol_name, "sr_bind_local_sized") == NULL;- In
SymBind.c:62:
ok = ok && r.symbol_name != NULL;
ok = ok && ZstrFindSubstring(r.symbol_name, "sr_bind_global_sized") != NULL;
ok = ok && ZstrFindSubstring(r.symbol_name, "sr_bind_local_sized") == NULL;
SymbolResolverDeinit(&res);- In
SymBind.c:81:
bool ok = SymbolResolverResolve(&res, (void *)&sr_bind_global_zero, &r);
ok = ok && r.symbol_name != NULL;
ok = ok && ZstrFindSubstring(r.symbol_name, "sr_bind_global_zero") != NULL;
ok = ok && ZstrFindSubstring(r.symbol_name, "sr_bind_local_zero") == NULL;- In
SymBind.c:82:
ok = ok && r.symbol_name != NULL;
ok = ok && ZstrFindSubstring(r.symbol_name, "sr_bind_global_zero") != NULL;
ok = ok && ZstrFindSubstring(r.symbol_name, "sr_bind_local_zero") == NULL;
SymbolResolverDeinit(&res); ResolvedSymbol r;
bool ok = SymbolResolverResolve(&res, (void *)&scd_marker, &r);
ok = ok && r.symbol_name && ZstrFindSubstring(r.symbol_name, "scd_marker") != NULL;
SymbolResolverDeinit(&res); ResolvedSymbol r;
bool ok = SymbolResolverResolve(&res, (void *)&scd_marker, &r);
ok = ok && r.symbol_name && ZstrFindSubstring(r.symbol_name, "scd_marker") != NULL;
ok = ok && DebugAllocatorLiveCount(&alloc) > baseline;- In
SidecarSub.c:45:
ResolvedSymbol r;
bool ok = SymbolResolverResolve(&res, (void *)addr, &r);
ok = ok && r.symbol_name && ZstrFindSubstring(r.symbol_name, "subdir_marker") != NULL;
ok = ok && r.offset == 0;
ok = ok && (r.module_base + r.symbol_value + r.offset) == addr;- In
SidecarSub.c:69:
ResolvedSymbol r;
bool ok = SymbolResolverResolve(&res, (void *)&subdir_marker, &r);
ok = ok && r.symbol_name && ZstrFindSubstring(r.symbol_name, "subdir_marker") != NULL;
ok = ok && DebugAllocatorLiveCount(&alloc) > baseline;- In
Sidecar.c:47:
bool ok = SymbolResolverResolve(&res, (void *)&sidecar_marker, &r);
ok = ok && r.module_path && r.module_path[0] != '\0';
ok = ok && r.symbol_name && ZstrFindSubstring(r.symbol_name, "sidecar_marker") != NULL;
// Entry address -> offset zero, reconstruction holds against the
// sidecar-sourced symbol value, and the sidecar's `.symtab` carries a
- In
Sidecar.c:56:
// `.debug_line` lives only in the sidecar too: a source file/line for
// this TU proves the sidecar DWARF was consulted.
ok = ok && r.source_file && ZstrFindSubstring(r.source_file, "Sidecar.c") != NULL;
ok = ok && r.source_line > 0;- In
Sidecar.c:84:
// The marker is named only via the opened sidecar, proving the cache
// entry actually carries one.
ok = ok && r.symbol_name && ZstrFindSubstring(r.symbol_name, "sidecar_marker") != NULL;
ok = ok && DebugAllocatorLiveCount(&alloc) > baseline; ResolvedSymbol r;
bool ok = SymbolResolverResolve(&res, (void *)addr, &r);
ok = ok && r.symbol_name && ZstrFindSubstring(r.symbol_name, "df_marker_a") != NULL;
// Entry address: offset 0, reconstruction holds against the DWARF-sourced
// low_pc, and the body has a real (small, non-zero) size.
ResolvedSymbol rlast;
ok = SymbolResolverResolve(&res, (void *)(addr + r.symbol_size - 1), &rlast);
ok = ok && rlast.symbol_name && ZstrFindSubstring(rlast.symbol_name, "df_marker_a") != NULL;
ok = ok && rlast.symbol_value == r.symbol_value;
ok = ok && rlast.offset == r.symbol_size - 1; bool ok = SymbolResolverResolve(&res, (void *)&df_marker_a, &ra);
ok = ok && SymbolResolverResolve(&res, (void *)&df_marker_b, &rb);
ok = ok && ra.source_file && ZstrFindSubstring(ra.source_file, "DwarfFallback.c") != NULL;
ok = ok && rb.source_file && ZstrFindSubstring(rb.source_file, "DwarfFallback.c") != NULL;
ok = ok && ra.source_line > 0 && rb.source_line > 0; ok = ok && SymbolResolverResolve(&res, (void *)&df_marker_b, &rb);
ok = ok && ra.source_file && ZstrFindSubstring(ra.source_file, "DwarfFallback.c") != NULL;
ok = ok && rb.source_file && ZstrFindSubstring(rb.source_file, "DwarfFallback.c") != NULL;
ok = ok && ra.source_line > 0 && rb.source_line > 0;
ok = ok && ra.source_line != rb.source_line; // The name came from DWARF, proving the function table was built (and the
// line table alongside it).
ok = ok && r.symbol_name && ZstrFindSubstring(r.symbol_name, "df_marker_a") != NULL;
ok = ok && DebugAllocatorLiveCount(&alloc) > baseline;- In
Bias.c:66:
ResolvedSymbol r;
bool ok = SymbolResolverResolve(&res, addr, &r);
ok = ok && r.symbol_name && ZstrFindSubstring(r.symbol_name, "symres_bias_data") != NULL;
ok = ok && r.offset == 0;
ok = ok && (r.module_base + r.symbol_value + r.offset) == (u64)addr;- In
Bias.c:92:
ok = ok && SymbolResolverResolve(&res, (void *)(base + K), &rk);
ok = ok && r0.symbol_name && rk.symbol_name;
ok = ok && ZstrFindSubstring(rk.symbol_name, "symres_bias_data") != NULL;
ok = ok && rk.symbol_value == r0.symbol_value;
ok = ok && rk.offset == K;- In
Http.c:56:
// - includes a Content-Length: 11 (length of "<h1>hi</h1>")
// - ends with the body
bool ok = StrLen(&wire) > 0 && ZstrFindSubstring(StrBegin(&wire), "HTTP/1.1 200 OK\r\n") == StrBegin(&wire) &&
ZstrFindSubstring(StrBegin(&wire), "Content-Type: text/html\r\n") != NULL &&
ZstrFindSubstring(StrBegin(&wire), "Content-Length: 11\r\n") != NULL &&- In
Http.c:57:
// - ends with the body
bool ok = StrLen(&wire) > 0 && ZstrFindSubstring(StrBegin(&wire), "HTTP/1.1 200 OK\r\n") == StrBegin(&wire) &&
ZstrFindSubstring(StrBegin(&wire), "Content-Type: text/html\r\n") != NULL &&
ZstrFindSubstring(StrBegin(&wire), "Content-Length: 11\r\n") != NULL &&
ZstrFindSubstring(StrBegin(&wire), "\r\n\r\n<h1>hi</h1>") != NULL;- In
Http.c:58:
bool ok = StrLen(&wire) > 0 && ZstrFindSubstring(StrBegin(&wire), "HTTP/1.1 200 OK\r\n") == StrBegin(&wire) &&
ZstrFindSubstring(StrBegin(&wire), "Content-Type: text/html\r\n") != NULL &&
ZstrFindSubstring(StrBegin(&wire), "Content-Length: 11\r\n") != NULL &&
ZstrFindSubstring(StrBegin(&wire), "\r\n\r\n<h1>hi</h1>") != NULL;- In
Http.c:59:
ZstrFindSubstring(StrBegin(&wire), "Content-Type: text/html\r\n") != NULL &&
ZstrFindSubstring(StrBegin(&wire), "Content-Length: 11\r\n") != NULL &&
ZstrFindSubstring(StrBegin(&wire), "\r\n\r\n<h1>hi</h1>") != NULL;
StrDeinit(&wire);- In
MachO.c:622:
const MachoSymbol *sym = MachoResolveAddress(&m, vaddr);
bool ok = sym != NULL && sym->name != NULL &&
ZstrFindSubstring(sym->name, "test_macho_resolves_running_binary_symbol") != NULL;
MachoDeinit(&m);- In
Stripped.c:84:
if (built && VecLen(&fns.entries) > 0) {
const DwarfFunction *f = DwarfFunctionsResolve(&fns, file_relative);
ok = f && f->name && ZstrFindSubstring(f->name, expect_name) != NULL;
DwarfFunctionsDeinit(&fns);
}- In
Dwarf.c:74:
if (built) {
const DwarfLineEntry *e = DwarfLinesResolve(&lines, file_relative);
if (e && e->file && ZstrFindSubstring(e->file, "Dwarf.c") != NULL && e->line > 0) {
ok = true;
}- In
Dwarf.c:183:
if (built && VecLen(&fns.entries) > 0) {
const DwarfFunction *f = DwarfFunctionsResolve(&fns, file_relative);
ok = f != NULL && f->name != NULL && ZstrFindSubstring(f->name, "dwarf_marker_helper") != NULL;
DwarfFunctionsDeinit(&fns);
}- In
Dwarf.c:591:
// Address 0x2000 -> source.c:10
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0x2000);
ok = ok && e && e->file && ZstrFindSubstring(e->file, "source.c") != NULL && e->line == 10;
// An address inside the first row's range still maps to line 10.
- In
Dwarf.c:1127:
ok = ok && DwarfLinesResolve(&fx.lines, 0x3001) == NULL;
// The file is source.c (default file 1).
ok = ok && e && e->file && ZstrFindSubstring(e->file, "source.c") != NULL;
lines_fixture_close(&fx);- In
Dwarf.c:1267:
// to a constant (e.g. 42) would index past the file table -> empty/NULL
// file; `f` left at its init 0 would also not select file 2.
ok = ok && e && e->file && ZstrFindSubstring(e->file, "other.c") != NULL;
ok = ok && e && e->file && ZstrFindSubstring(e->file, "source.c") == NULL;
lines_fixture_close(&fx);- In
Dwarf.c:1268:
// file; `f` left at its init 0 would also not select file 2.
ok = ok && e && e->file && ZstrFindSubstring(e->file, "other.c") != NULL;
ok = ok && e && e->file && ZstrFindSubstring(e->file, "source.c") == NULL;
lines_fixture_close(&fx);
return ok;- In
Dwarf.c:1293:
bool ok = true;
const DwarfLineEntry *e = DwarfLinesResolve(&fx.lines, 0xB800);
ok = ok && e && e->file && ZstrFindSubstring(e->file, "source.c") != NULL;
lines_fixture_close(&fx);
return ok;- In
Dwarf.c:1715:
ok = ok && DwarfLinesResolve(&lines, 0x6001) == NULL;
// The file string came through.
ok = ok && e->file && ZstrFindSubstring(e->file, "source.c") != NULL;
DwarfLinesDeinit(&lines);
}- In
Dwarf.c:2143:
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0x2000);
ok = ok && e && e->file && ZstrFindSubstring(e->file, "second.c") != NULL;
ok = ok && e && e->dir && ZstrFindSubstring(e->dir, "real_dir") != NULL;
ok = ok && e && e->line == 10;- In
Dwarf.c:2144:
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0x2000);
ok = ok && e && e->file && ZstrFindSubstring(e->file, "second.c") != NULL;
ok = ok && e && e->dir && ZstrFindSubstring(e->dir, "real_dir") != NULL;
ok = ok && e && e->line == 10;
ok = ok && e && e->is_stmt == true;- In
Dwarf.c:2155:
e = DwarfLinesResolve(&lines, 0x2008);
ok = ok && e && e->line == 20;
ok = ok && e && e->file && ZstrFindSubstring(e->file, "second.c") != NULL;
ok = ok && e && e->dir && ZstrFindSubstring(e->dir, "real_dir") != NULL;- In
Dwarf.c:2156:
ok = ok && e && e->line == 20;
ok = ok && e && e->file && ZstrFindSubstring(e->file, "second.c") != NULL;
ok = ok && e && e->dir && ZstrFindSubstring(e->dir, "real_dir") != NULL;
// Below the first address and at/after end_sequence -> unresolved.
- In
Dwarf.c:2209:
bool ok = true;
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0x3000);
ok = ok && e && e->file && ZstrFindSubstring(e->file, "first.c") != NULL;
ok = ok && e && e->line == 7;
ok = ok && e && e->dir == NULL;- In
Dwarf.c:2338:
// Sequence 1: 0x6000 -> second.c:100
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0x6000);
ok = ok && e && e->file && ZstrFindSubstring(e->file, "second.c") != NULL;
ok = ok && e && e->line == 100;- In
Dwarf.c:2344:
// file=1 and line=1 between sequences).
e = DwarfLinesResolve(&lines, 0x7000);
ok = ok && e && e->file && ZstrFindSubstring(e->file, "first.c") != NULL;
ok = ok && e && e->line == 5;- In
Dwarf.c:2763:
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0x2000);
ok = ok && e && e->line == 10;
ok = ok && e && e->file && ZstrFindSubstring(e->file, "second.c") != NULL;
ok = ok && e && e->dir && ZstrFindSubstring(e->dir, "real_dir") != NULL;- In
Dwarf.c:2764:
ok = ok && e && e->line == 10;
ok = ok && e && e->file && ZstrFindSubstring(e->file, "second.c") != NULL;
ok = ok && e && e->dir && ZstrFindSubstring(e->dir, "real_dir") != NULL;
DwarfLinesDeinit(&lines);- In
Dwarf.c:2818:
// so the row exists at 0x4000 with line 42 and file "first.c".
ok = ok && e && e->address == 0x4000 && e->line == 42;
ok = ok && e && e->file && ZstrFindSubstring(e->file, "first.c") != NULL;
DwarfLinesDeinit(&lines);- In
Dwarf.c:2875:
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0x4400);
ok = ok && e && e->address == 0x4400 && e->line == 22;
ok = ok && e && e->file && ZstrFindSubstring(e->file, "second.c") != NULL;
DwarfLinesDeinit(&lines);- In
Dwarf.c:3214:
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0x3300);
// file present, but dir index 0 -> dir must be NULL, not pool+42.
ok = ok && e && e->file && ZstrFindSubstring(e->file, "only.c") != NULL;
ok = ok && e && e->dir == NULL;
DwarfLinesDeinit(&lines);
Last updated on