mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
- Test runner will also check for leaks.
- `write` of qoi would leak memory. - Issue when having an empty `Path` or just "." - `set_env` would leak memory.
This commit is contained in:
@@ -74,7 +74,7 @@ import std::io;
|
||||
fn usz! write(String filename, char[] input, QOIDesc* desc) => @pool()
|
||||
{
|
||||
// encode data
|
||||
char[] output = new_encode(input, desc)!;
|
||||
char[] output = new_encode(input, desc, allocator: allocator::temp())!;
|
||||
|
||||
// open file
|
||||
File! f = file::open(filename, "wb");
|
||||
|
||||
@@ -256,13 +256,12 @@ fn bool run_tests(String[] args, TestUnit[] tests) @private
|
||||
name.appendf("Testing %s ", unit.name);
|
||||
name.append_repeat('.', max_name - unit.name.len + 2);
|
||||
io::printf("%s ", name.str_view());
|
||||
|
||||
TrackingAllocator mem;
|
||||
mem.init(allocator::heap());
|
||||
if (libc::setjmp(&context.buf) == 0)
|
||||
{
|
||||
mute_output();
|
||||
TrackingAllocator mem;
|
||||
mem.init(allocator::heap());
|
||||
bool has_leaks;
|
||||
mem.clear();
|
||||
mem::@scoped(&mem)
|
||||
{
|
||||
$if(!$$OLD_TEST):
|
||||
@@ -274,22 +273,25 @@ fn bool run_tests(String[] args, TestUnit[] tests) @private
|
||||
continue;
|
||||
}
|
||||
$endif
|
||||
has_leaks = mem.has_leaks();
|
||||
};
|
||||
mem.free();
|
||||
unmute_output(false); // all good, discard output
|
||||
|
||||
io::printf(test_context.has_ansi_codes ? "[\e[0;32mPASS\e[0m]" : "[PASS]");
|
||||
tests_passed++;
|
||||
|
||||
if (has_leaks) io::print(" LEAKS!");
|
||||
io::printn();
|
||||
|
||||
if (mem.has_leaks())
|
||||
{
|
||||
io::print(test_context.has_ansi_codes ? "[\e[0;31mFAIL\e[0m]" : "[FAIL]");
|
||||
io::printn(" LEAKS DETECTED!");
|
||||
mem.print_report();
|
||||
}
|
||||
else
|
||||
{
|
||||
io::printfn(test_context.has_ansi_codes ? "[\e[0;32mPASS\e[0m]" : "[PASS]");
|
||||
tests_passed++;
|
||||
}
|
||||
if (test_context.teardown_fn)
|
||||
{
|
||||
test_context.teardown_fn();
|
||||
}
|
||||
}
|
||||
mem.free();
|
||||
}
|
||||
io::printfn("\n%d test%s run.\n", test_count-tests_skipped, test_count > 1 ? "s" : "");
|
||||
|
||||
|
||||
@@ -395,7 +395,7 @@ fn Path! Path.parent(self)
|
||||
|
||||
fn String! normalize(String path_str, PathEnv path_env = DEFAULT_PATH_ENV)
|
||||
{
|
||||
if (!path_str.len) return "";
|
||||
if (!path_str.len) return path_str;
|
||||
usz path_start = volume_name_len(path_str, path_env)!;
|
||||
if (path_start > 0 && path_env == PathEnv.WIN32)
|
||||
{
|
||||
@@ -506,7 +506,11 @@ fn String! normalize(String path_str, PathEnv path_env = DEFAULT_PATH_ENV)
|
||||
if (len > path_start + 1 && is_separator(path_str[len - 1], path_env)) len--;
|
||||
if (path_str.len > len) path_str.ptr[len] = 0;
|
||||
// Empty path after normalization -> "."
|
||||
if (!len) return ".";
|
||||
if (!len)
|
||||
{
|
||||
path_str[0] = '.';
|
||||
return path_str[:1];
|
||||
}
|
||||
return path_str[:len];
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ fn bool set_var(String name, String value, bool overwrite = true) => @pool()
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setenvironmentvariable
|
||||
return (win32::setEnvironmentVariableW(wname, value.to_temp_wstring()) ?? 1) == 0;
|
||||
$case env::LIBC && !env::WIN32:
|
||||
return libc::setenv(name.zstr_tcopy(), value.zstr_copy(), (int)overwrite) == 0;
|
||||
return libc::setenv(name.zstr_tcopy(), value.zstr_tcopy(), (int)overwrite) == 0;
|
||||
$default:
|
||||
return false;
|
||||
$endswitch
|
||||
|
||||
Reference in New Issue
Block a user