mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 03:51:18 +00:00
Update stdlib with new syntax for short function decl.
This commit is contained in:
@@ -71,24 +71,21 @@ import std::io;
|
||||
@param [in] input `The raw RGB or RGBA pixels to encode`
|
||||
@param [&in] desc `The descriptor of the image`
|
||||
*>
|
||||
fn usz! write(String filename, char[] input, QOIDesc* desc)
|
||||
fn usz! write(String filename, char[] input, QOIDesc* desc) => @pool()
|
||||
{
|
||||
@pool()
|
||||
{
|
||||
// encode data
|
||||
char[] output = new_encode(input, desc)!;
|
||||
// encode data
|
||||
char[] output = new_encode(input, desc)!;
|
||||
|
||||
// open file
|
||||
File! f = file::open(filename, "wb");
|
||||
if (catch f) return QOIError.FILE_OPEN_FAILED?;
|
||||
// open file
|
||||
File! f = file::open(filename, "wb");
|
||||
if (catch f) return QOIError.FILE_OPEN_FAILED?;
|
||||
|
||||
// write data to file and close it
|
||||
usz! written = f.write(output);
|
||||
if (catch written) return QOIError.FILE_WRITE_FAILED?;
|
||||
if (catch f.close()) return QOIError.FILE_WRITE_FAILED?;
|
||||
// write data to file and close it
|
||||
usz! written = f.write(output);
|
||||
if (catch written) return QOIError.FILE_WRITE_FAILED?;
|
||||
if (catch f.close()) return QOIError.FILE_WRITE_FAILED?;
|
||||
|
||||
return written;
|
||||
};
|
||||
return written;
|
||||
}
|
||||
|
||||
|
||||
@@ -113,16 +110,12 @@ fn usz! write(String filename, char[] input, QOIDesc* desc)
|
||||
@param [&out] desc `The descriptor to fill with the image's info`
|
||||
@param channels `The channels to be used`
|
||||
*>
|
||||
fn char[]! new_read(String filename, QOIDesc* desc, QOIChannels channels = AUTO, Allocator allocator = allocator::heap())
|
||||
fn char[]! new_read(String filename, QOIDesc* desc, QOIChannels channels = AUTO, Allocator allocator = allocator::heap()) => @pool(allocator)
|
||||
{
|
||||
@pool(allocator)
|
||||
{
|
||||
// read file
|
||||
char[] data = file::load_temp(filename) ?? QOIError.FILE_OPEN_FAILED?!;
|
||||
|
||||
// pass data to decode function
|
||||
return new_decode(data, desc, channels, allocator);
|
||||
};
|
||||
// read file
|
||||
char[] data = file::load_temp(filename) ?? QOIError.FILE_OPEN_FAILED?!;
|
||||
// pass data to decode function
|
||||
return new_decode(data, desc, channels, allocator);
|
||||
}
|
||||
|
||||
fn char[]! read(String filename, QOIDesc* desc, QOIChannels channels = AUTO, Allocator allocator = allocator::heap()) @deprecated("Use new_read")
|
||||
|
||||
@@ -49,13 +49,10 @@ fn void TrackingAllocator.free(&self)
|
||||
<*
|
||||
@return "the total allocated memory not yet freed."
|
||||
*>
|
||||
fn usz TrackingAllocator.allocated(&self)
|
||||
fn usz TrackingAllocator.allocated(&self) => @pool()
|
||||
{
|
||||
usz allocated = 0;
|
||||
@pool()
|
||||
{
|
||||
foreach (&allocation : self.map.value_tlist()) allocated += allocation.size;
|
||||
};
|
||||
foreach (&allocation : self.map.value_tlist()) allocated += allocation.size;
|
||||
return allocated;
|
||||
}
|
||||
|
||||
@@ -118,99 +115,95 @@ fn void TrackingAllocator.clear(&self)
|
||||
|
||||
fn void TrackingAllocator.print_report(&self) => self.fprint_report(io::stdout())!!;
|
||||
|
||||
fn void! TrackingAllocator.fprint_report(&self, OutStream out)
|
||||
fn void! TrackingAllocator.fprint_report(&self, OutStream out) => @pool()
|
||||
{
|
||||
|
||||
usz total = 0;
|
||||
usz entries = 0;
|
||||
bool leaks = false;
|
||||
@pool()
|
||||
{
|
||||
Allocation[] allocs = self.map.value_tlist();
|
||||
if (allocs.len)
|
||||
{
|
||||
if (!allocs[0].backtrace[0])
|
||||
{
|
||||
io::fprintn(out, "======== Memory Report ========")!;
|
||||
io::fprintn(out, "Size in bytes Address")!;
|
||||
foreach (i, &allocation : allocs)
|
||||
{
|
||||
entries++;
|
||||
total += allocation.size;
|
||||
io::fprintfn(out, "%13s %p", allocation.size, allocation.ptr)!;
|
||||
}
|
||||
io::fprintn(out, "===============================")!;
|
||||
|
||||
}
|
||||
else
|
||||
Allocation[] allocs = self.map.value_tlist();
|
||||
if (allocs.len)
|
||||
{
|
||||
if (!allocs[0].backtrace[0])
|
||||
{
|
||||
io::fprintn(out, "======== Memory Report ========")!;
|
||||
io::fprintn(out, "Size in bytes Address")!;
|
||||
foreach (i, &allocation : allocs)
|
||||
{
|
||||
io::fprintn(out, "================================== Memory Report ==================================")!;
|
||||
io::fprintn(out, "Size in bytes Address Function ")!;
|
||||
foreach (i, &allocation : allocs)
|
||||
{
|
||||
entries++;
|
||||
total += allocation.size;
|
||||
BacktraceList backtraces = {};
|
||||
Backtrace trace = backtrace::BACKTRACE_UNKNOWN;
|
||||
if (allocation.backtrace[3])
|
||||
{
|
||||
trace = backtrace::symbolize_backtrace(allocation.backtrace[3:1], allocator::temp()).get(0) ?? backtrace::BACKTRACE_UNKNOWN;
|
||||
}
|
||||
if (trace.function.len) leaks = true;
|
||||
io::fprintfn(out, "%13s %p %s:%d", allocation.size,
|
||||
allocation.ptr, trace.function.len ? trace.function : "???",
|
||||
trace.line ? trace.line : 0)!;
|
||||
}
|
||||
io::fprintn(out, "===================================================================================")!;
|
||||
entries++;
|
||||
total += allocation.size;
|
||||
io::fprintfn(out, "%13s %p", allocation.size, allocation.ptr)!;
|
||||
}
|
||||
io::fprintn(out, "===============================")!;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
io::fprintn(out, "* NO ALLOCATIONS FOUND *")!;
|
||||
}
|
||||
io::fprintfn(out, "- Total currently allocated memory: %d", total)!;
|
||||
io::fprintfn(out, "- Total current allocations: %d", entries)!;
|
||||
io::fprintfn(out, "- Total allocations (freed and retained): %d", self.allocs_total)!;
|
||||
io::fprintfn(out, "- Total allocated memory (freed and retained): %d", self.mem_total)!;
|
||||
if (leaks)
|
||||
{
|
||||
io::fprintn(out)!;
|
||||
io::fprintn(out, "Full leak report:")!;
|
||||
io::fprintn(out, "================================== Memory Report ==================================")!;
|
||||
io::fprintn(out, "Size in bytes Address Function ")!;
|
||||
foreach (i, &allocation : allocs)
|
||||
{
|
||||
if (!allocation.backtrace[3])
|
||||
{
|
||||
io::fprintfn(out, "Allocation %d (%d bytes) - no backtrace available.", i + 1, allocation.size)!;
|
||||
continue;
|
||||
}
|
||||
entries++;
|
||||
total += allocation.size;
|
||||
BacktraceList backtraces = {};
|
||||
usz end = MAX_BACKTRACE;
|
||||
foreach (j, val : allocation.backtrace)
|
||||
Backtrace trace = backtrace::BACKTRACE_UNKNOWN;
|
||||
if (allocation.backtrace[3])
|
||||
{
|
||||
if (!val)
|
||||
{
|
||||
end = j;
|
||||
break;
|
||||
}
|
||||
trace = backtrace::symbolize_backtrace(allocation.backtrace[3:1], allocator::temp()).get(0) ?? backtrace::BACKTRACE_UNKNOWN;
|
||||
}
|
||||
BacktraceList list = backtrace::symbolize_backtrace(allocation.backtrace[3..(end - 1)], allocator::temp())!;
|
||||
io::fprintfn(out, "Allocation %d (%d bytes): ", i + 1, allocation.size)!;
|
||||
foreach (trace : list)
|
||||
if (trace.function.len) leaks = true;
|
||||
io::fprintfn(out, "%13s %p %s:%d", allocation.size,
|
||||
allocation.ptr, trace.function.len ? trace.function : "???",
|
||||
trace.line ? trace.line : 0)!;
|
||||
}
|
||||
io::fprintn(out, "===================================================================================")!;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
io::fprintn(out, "* NO ALLOCATIONS FOUND *")!;
|
||||
}
|
||||
io::fprintfn(out, "- Total currently allocated memory: %d", total)!;
|
||||
io::fprintfn(out, "- Total current allocations: %d", entries)!;
|
||||
io::fprintfn(out, "- Total allocations (freed and retained): %d", self.allocs_total)!;
|
||||
io::fprintfn(out, "- Total allocated memory (freed and retained): %d", self.mem_total)!;
|
||||
if (leaks)
|
||||
{
|
||||
io::fprintn(out)!;
|
||||
io::fprintn(out, "Full leak report:")!;
|
||||
foreach (i, &allocation : allocs)
|
||||
{
|
||||
if (!allocation.backtrace[3])
|
||||
{
|
||||
io::fprintfn(out, "Allocation %d (%d bytes) - no backtrace available.", i + 1, allocation.size)!;
|
||||
continue;
|
||||
}
|
||||
BacktraceList backtraces = {};
|
||||
usz end = MAX_BACKTRACE;
|
||||
foreach (j, val : allocation.backtrace)
|
||||
{
|
||||
if (!val)
|
||||
{
|
||||
if (trace.has_file())
|
||||
{
|
||||
io::fprintfn(out, " %s (in %s:%d)", trace.function, trace.file, trace.line);
|
||||
continue;
|
||||
}
|
||||
if (trace.is_unknown())
|
||||
{
|
||||
io::fprintfn(out, " ??? (in unknown)");
|
||||
continue;
|
||||
}
|
||||
io::fprintfn(out, " %s (source unavailable)", trace.function);
|
||||
end = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
BacktraceList list = backtrace::symbolize_backtrace(allocation.backtrace[3..(end - 1)], allocator::temp())!;
|
||||
io::fprintfn(out, "Allocation %d (%d bytes): ", i + 1, allocation.size)!;
|
||||
foreach (trace : list)
|
||||
{
|
||||
if (trace.has_file())
|
||||
{
|
||||
io::fprintfn(out, " %s (in %s:%d)", trace.function, trace.file, trace.line);
|
||||
continue;
|
||||
}
|
||||
if (trace.is_unknown())
|
||||
{
|
||||
io::fprintfn(out, " ??? (in unknown)");
|
||||
continue;
|
||||
}
|
||||
io::fprintfn(out, " %s (source unavailable)", trace.function);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
@@ -62,38 +62,37 @@ macro anycast(any v, $Type) @builtin
|
||||
return ($Type*)v.ptr;
|
||||
}
|
||||
|
||||
fn bool print_backtrace(String message, int backtraces_to_ignore) @if(env::NATIVE_STACKTRACE)
|
||||
fn bool print_backtrace(String message, int backtraces_to_ignore) @if(env::NATIVE_STACKTRACE) => @pool()
|
||||
{
|
||||
@pool()
|
||||
void*[256] buffer;
|
||||
void*[] backtraces = backtrace::capture_current(&buffer);
|
||||
backtraces_to_ignore++;
|
||||
BacktraceList! backtrace = backtrace::symbolize_backtrace(backtraces, allocator::temp());
|
||||
if (catch backtrace) return false;
|
||||
if (backtrace.len() <= backtraces_to_ignore) return false;
|
||||
io::eprint("\nERROR: '");
|
||||
io::eprint(message);
|
||||
io::eprintn("'");
|
||||
foreach (i, &trace : backtrace)
|
||||
{
|
||||
void*[256] buffer;
|
||||
void*[] backtraces = backtrace::capture_current(&buffer);
|
||||
backtraces_to_ignore++;
|
||||
BacktraceList! backtrace = backtrace::symbolize_backtrace(backtraces, allocator::temp());
|
||||
if (catch backtrace) return false;
|
||||
if (backtrace.len() <= backtraces_to_ignore) return false;
|
||||
io::eprint("\nERROR: '");
|
||||
io::eprint(message);
|
||||
io::eprintn("'");
|
||||
foreach (i, &trace : backtrace)
|
||||
if (i < backtraces_to_ignore) continue;
|
||||
String inline_suffix = trace.is_inline ? " [inline]" : "";
|
||||
if (trace.is_unknown())
|
||||
{
|
||||
if (i < backtraces_to_ignore) continue;
|
||||
String inline_suffix = trace.is_inline ? " [inline]" : "";
|
||||
if (trace.is_unknown())
|
||||
{
|
||||
io::eprintfn(" in ???%s", inline_suffix);
|
||||
continue;
|
||||
}
|
||||
if (trace.has_file())
|
||||
{
|
||||
io::eprintfn(" in %s (%s:%d) [%s]%s", trace.function, trace.file, trace.line, trace.object_file, inline_suffix);
|
||||
continue;
|
||||
}
|
||||
io::eprintfn(" in %s (source unavailable) [%s]%s", trace.function, trace.object_file, inline_suffix);
|
||||
io::eprintfn(" in ???%s", inline_suffix);
|
||||
continue;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
if (trace.has_file())
|
||||
{
|
||||
io::eprintfn(" in %s (%s:%d) [%s]%s", trace.function, trace.file, trace.line, trace.object_file, inline_suffix);
|
||||
continue;
|
||||
}
|
||||
io::eprintfn(" in %s (source unavailable) [%s]%s", trace.function, trace.object_file, inline_suffix);
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
fn void default_panic(String message, String file, String function, uint line) @if(env::NATIVE_STACKTRACE)
|
||||
{
|
||||
$if $defined(io::stderr):
|
||||
|
||||
@@ -168,10 +168,7 @@ fn bool run_benchmarks(BenchmarkUnit[] benchmarks) @if(!$$OLD_TEST)
|
||||
return true;
|
||||
}
|
||||
|
||||
fn bool default_benchmark_runner(String[] args)
|
||||
fn bool default_benchmark_runner(String[] args) => @pool()
|
||||
{
|
||||
@pool()
|
||||
{
|
||||
return run_benchmarks(benchmark_collection_create(allocator::temp()));
|
||||
};
|
||||
return run_benchmarks(benchmark_collection_create(allocator::temp()));
|
||||
}
|
||||
|
||||
@@ -66,20 +66,18 @@ fn int cmp_test_unit(TestUnit a, TestUnit b)
|
||||
return (int)(an - bn);
|
||||
}
|
||||
|
||||
fn bool terminal_has_ansi_codes() @local
|
||||
fn bool terminal_has_ansi_codes() @local => @pool()
|
||||
{
|
||||
@pool()
|
||||
|
||||
if (try v = env::get_var_temp("TERM"))
|
||||
{
|
||||
if (try v = env::get_var_temp("TERM"))
|
||||
{
|
||||
if (v.contains("xterm") || v.contains("vt100") || v.contains("screen")) return true;
|
||||
}
|
||||
$if env::WIN32 || env::NO_LIBC:
|
||||
return false;
|
||||
$else
|
||||
return io::stdout().isatty();
|
||||
$endif
|
||||
};
|
||||
if (v.contains("xterm") || v.contains("vt100") || v.contains("screen")) return true;
|
||||
}
|
||||
$if env::WIN32 || env::NO_LIBC:
|
||||
return false;
|
||||
$else
|
||||
return io::stdout().isatty();
|
||||
$endif
|
||||
}
|
||||
|
||||
fn void test_panic(String message, String file, String function, uint line) @local
|
||||
@@ -304,12 +302,9 @@ fn bool run_tests(String[] args, TestUnit[] tests) @private
|
||||
return n_failed == 0;
|
||||
}
|
||||
|
||||
fn bool default_test_runner(String[] args)
|
||||
fn bool default_test_runner(String[] args) => @pool()
|
||||
{
|
||||
@pool()
|
||||
{
|
||||
assert(test_context == null, "test suite is already running");
|
||||
return run_tests(args, test_collection_create(allocator::temp()));
|
||||
};
|
||||
assert(test_context == null, "test suite is already running");
|
||||
return run_tests(args, test_collection_create(allocator::temp()));
|
||||
}
|
||||
|
||||
|
||||
@@ -52,14 +52,11 @@ fn ZString tformat_zstr(String fmt, args...)
|
||||
@param [inout] allocator `The allocator to use`
|
||||
@param [in] fmt `The formatting string`
|
||||
*>
|
||||
fn String format(String fmt, args..., Allocator allocator)
|
||||
fn String format(String fmt, args..., Allocator allocator) => @pool(allocator)
|
||||
{
|
||||
@pool(allocator)
|
||||
{
|
||||
DString str = dstring::temp_with_capacity(fmt.len + args.len * 8);
|
||||
str.appendf(fmt, ...args);
|
||||
return str.copy_str(allocator);
|
||||
};
|
||||
DString str = dstring::temp_with_capacity(fmt.len + args.len * 8);
|
||||
str.appendf(fmt, ...args);
|
||||
return str.copy_str(allocator);
|
||||
}
|
||||
|
||||
<*
|
||||
@@ -87,14 +84,11 @@ fn String tformat(String fmt, args...)
|
||||
@param [in] fmt `The formatting string`
|
||||
@param [inout] allocator `The allocator to use`
|
||||
*>
|
||||
fn ZString new_format_zstr(String fmt, args..., Allocator allocator = allocator::heap())
|
||||
fn ZString new_format_zstr(String fmt, args..., Allocator allocator = allocator::heap()) => @pool(allocator)
|
||||
{
|
||||
@pool(allocator)
|
||||
{
|
||||
DString str = dstring::temp_with_capacity(fmt.len + args.len * 8);
|
||||
str.appendf(fmt, ...args);
|
||||
return str.copy_zstr(allocator);
|
||||
};
|
||||
DString str = dstring::temp_with_capacity(fmt.len + args.len * 8);
|
||||
str.appendf(fmt, ...args);
|
||||
return str.copy_zstr(allocator);
|
||||
}
|
||||
|
||||
<*
|
||||
|
||||
@@ -70,12 +70,9 @@ fn void CsvRow.free(&self)
|
||||
self.allocator = null;
|
||||
}
|
||||
|
||||
fn void! CsvReader.skip_row(self) @maydiscard
|
||||
fn void! CsvReader.skip_row(self) @maydiscard => @pool()
|
||||
{
|
||||
@pool()
|
||||
{
|
||||
(void)io::treadline(self.stream);
|
||||
};
|
||||
(void)io::treadline(self.stream);
|
||||
}
|
||||
|
||||
macro void! CsvReader.@each_row(self, int rows = int.max; @body(String[] row)) @maydiscard
|
||||
|
||||
@@ -5,57 +5,48 @@ import libc;
|
||||
@require mode.len > 0
|
||||
@require filename.len > 0
|
||||
*>
|
||||
fn void*! native_fopen(String filename, String mode) @inline
|
||||
fn void*! native_fopen(String filename, String mode) @inline => @pool()
|
||||
{
|
||||
@pool()
|
||||
{
|
||||
$if env::WIN32:
|
||||
void* file = libc::_wfopen(filename.to_temp_wstring(), mode.to_temp_wstring())!;
|
||||
$else
|
||||
void* file = libc::fopen(filename.zstr_tcopy(), mode.zstr_tcopy());
|
||||
$endif
|
||||
return file ?: file_open_errno()?;
|
||||
};
|
||||
$if env::WIN32:
|
||||
void* file = libc::_wfopen(filename.to_temp_wstring(), mode.to_temp_wstring())!;
|
||||
$else
|
||||
void* file = libc::fopen(filename.zstr_tcopy(), mode.zstr_tcopy());
|
||||
$endif
|
||||
return file ?: file_open_errno()?;
|
||||
}
|
||||
|
||||
fn void! native_remove(String filename)
|
||||
fn void! native_remove(String filename) => @pool()
|
||||
{
|
||||
@pool()
|
||||
$if env::WIN32:
|
||||
CInt result = libc::_wremove(filename.to_temp_wstring())!;
|
||||
$else
|
||||
CInt result = libc::remove(filename.zstr_tcopy());
|
||||
$endif
|
||||
if (result)
|
||||
{
|
||||
$if env::WIN32:
|
||||
CInt result = libc::_wremove(filename.to_temp_wstring())!;
|
||||
$else
|
||||
CInt result = libc::remove(filename.zstr_tcopy());
|
||||
$endif
|
||||
if (result)
|
||||
switch (libc::errno())
|
||||
{
|
||||
switch (libc::errno())
|
||||
{
|
||||
case errno::ENOENT:
|
||||
return IoError.FILE_NOT_FOUND?;
|
||||
case errno::EACCES:
|
||||
default:
|
||||
return IoError.FILE_CANNOT_DELETE?;
|
||||
}
|
||||
case errno::ENOENT:
|
||||
return IoError.FILE_NOT_FOUND?;
|
||||
case errno::EACCES:
|
||||
default:
|
||||
return IoError.FILE_CANNOT_DELETE?;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
<*
|
||||
@require mode.len > 0
|
||||
@require filename.len > 0
|
||||
*>
|
||||
fn void*! native_freopen(void* file, String filename, String mode) @inline
|
||||
fn void*! native_freopen(void* file, String filename, String mode) @inline => @pool()
|
||||
{
|
||||
@pool()
|
||||
{
|
||||
$if env::WIN32:
|
||||
file = libc::_wfreopen(filename.to_temp_wstring(), mode.to_temp_wstring(), file)!;
|
||||
$else
|
||||
file = libc::freopen(filename.zstr_tcopy(), mode.zstr_tcopy(), file);
|
||||
$endif
|
||||
return file ?: file_open_errno()?;
|
||||
};
|
||||
$if env::WIN32:
|
||||
file = libc::_wfreopen(filename.to_temp_wstring(), mode.to_temp_wstring(), file)!;
|
||||
$else
|
||||
file = libc::freopen(filename.zstr_tcopy(), mode.zstr_tcopy(), file);
|
||||
$endif
|
||||
return file ?: file_open_errno()?;
|
||||
}
|
||||
|
||||
fn void! native_fseek(void* file, isz offset, Seek seek_mode) @inline
|
||||
|
||||
@@ -1,56 +1,50 @@
|
||||
module std::io::os;
|
||||
import libc, std::os, std::io;
|
||||
|
||||
fn void! native_stat(Stat* stat, String path) @if(env::DARWIN || env::LINUX || env::BSD_FAMILY)
|
||||
fn void! native_stat(Stat* stat, String path) @if(env::DARWIN || env::LINUX || env::BSD_FAMILY) => @pool()
|
||||
{
|
||||
@pool()
|
||||
$if env::DARWIN || env::LINUX || env::BSD_FAMILY:
|
||||
int res = libc::stat(path.zstr_tcopy(), stat);
|
||||
$else
|
||||
unreachable("Stat unimplemented");
|
||||
int res = 0;
|
||||
$endif
|
||||
if (res != 0)
|
||||
{
|
||||
$if env::DARWIN || env::LINUX || env::BSD_FAMILY:
|
||||
int res = libc::stat(path.zstr_tcopy(), stat);
|
||||
$else
|
||||
unreachable("Stat unimplemented");
|
||||
int res = 0;
|
||||
$endif
|
||||
if (res != 0)
|
||||
switch (libc::errno())
|
||||
{
|
||||
switch (libc::errno())
|
||||
{
|
||||
case errno::EBADF:
|
||||
return IoError.FILE_NOT_VALID?;
|
||||
case errno::EFAULT:
|
||||
unreachable("Invalid stat");
|
||||
case errno::EIO:
|
||||
return IoError.GENERAL_ERROR?;
|
||||
case errno::EACCES:
|
||||
return IoError.NO_PERMISSION?;
|
||||
case errno::ELOOP:
|
||||
return IoError.NO_PERMISSION?;
|
||||
case errno::ENAMETOOLONG:
|
||||
return IoError.NAME_TOO_LONG?;
|
||||
case errno::ENOENT:
|
||||
return IoError.FILE_NOT_FOUND?;
|
||||
case errno::ENOTDIR:
|
||||
return IoError.FILE_NOT_DIR?;
|
||||
case errno::EOVERFLOW:
|
||||
return IoError.GENERAL_ERROR?;
|
||||
default:
|
||||
return IoError.UNKNOWN_ERROR?;
|
||||
}
|
||||
case errno::EBADF:
|
||||
return IoError.FILE_NOT_VALID?;
|
||||
case errno::EFAULT:
|
||||
unreachable("Invalid stat");
|
||||
case errno::EIO:
|
||||
return IoError.GENERAL_ERROR?;
|
||||
case errno::EACCES:
|
||||
return IoError.NO_PERMISSION?;
|
||||
case errno::ELOOP:
|
||||
return IoError.NO_PERMISSION?;
|
||||
case errno::ENAMETOOLONG:
|
||||
return IoError.NAME_TOO_LONG?;
|
||||
case errno::ENOENT:
|
||||
return IoError.FILE_NOT_FOUND?;
|
||||
case errno::ENOTDIR:
|
||||
return IoError.FILE_NOT_DIR?;
|
||||
case errno::EOVERFLOW:
|
||||
return IoError.GENERAL_ERROR?;
|
||||
default:
|
||||
return IoError.UNKNOWN_ERROR?;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn usz! native_file_size(String path) @if(env::WIN32)
|
||||
fn usz! native_file_size(String path) @if(env::WIN32) => @pool()
|
||||
{
|
||||
@pool()
|
||||
{
|
||||
Win32_FILE_ATTRIBUTE_DATA data;
|
||||
win32::getFileAttributesExW(path.to_temp_wstring()!, Win32_GET_FILEEX_INFO_LEVELS.STANDARD, &data);
|
||||
Win32_LARGE_INTEGER size;
|
||||
size.lowPart = data.nFileSizeLow;
|
||||
size.highPart = data.nFileSizeHigh;
|
||||
return (usz)size.quadPart;
|
||||
};
|
||||
Win32_FILE_ATTRIBUTE_DATA data;
|
||||
win32::getFileAttributesExW(path.to_temp_wstring()!, Win32_GET_FILEEX_INFO_LEVELS.STANDARD, &data);
|
||||
Win32_LARGE_INTEGER size;
|
||||
size.lowPart = data.nFileSizeLow;
|
||||
size.highPart = data.nFileSizeHigh;
|
||||
return (usz)size.quadPart;
|
||||
}
|
||||
|
||||
fn usz! native_file_size(String path) @if(!env::WIN32 && !env::DARWIN)
|
||||
|
||||
@@ -11,16 +11,13 @@ fn Path! native_temp_directory(Allocator allocator = allocator::heap()) @if(!env
|
||||
return path::new("/tmp", allocator);
|
||||
}
|
||||
|
||||
fn Path! native_temp_directory(Allocator allocator = allocator::heap()) @if(env::WIN32)
|
||||
fn Path! native_temp_directory(Allocator allocator = allocator::heap()) @if(env::WIN32) => @pool(allocator)
|
||||
{
|
||||
@pool(allocator)
|
||||
{
|
||||
Win32_DWORD len = win32::getTempPathW(0, null);
|
||||
if (!len) return IoError.GENERAL_ERROR?;
|
||||
Char16[] buff = mem::temp_alloc_array(Char16, len + (usz)1);
|
||||
if (!win32::getTempPathW(len, buff)) return IoError.GENERAL_ERROR?;
|
||||
return path::new(string::temp_from_utf16(buff[:len]), allocator);
|
||||
};
|
||||
Win32_DWORD len = win32::getTempPathW(0, null);
|
||||
if (!len) return IoError.GENERAL_ERROR?;
|
||||
Char16[] buff = mem::temp_alloc_array(Char16, len + (usz)1);
|
||||
if (!win32::getTempPathW(len, buff)) return IoError.GENERAL_ERROR?;
|
||||
return path::new(string::temp_from_utf16(buff[:len]), allocator);
|
||||
}
|
||||
|
||||
module std::io::os @if(env::NO_LIBC);
|
||||
|
||||
@@ -29,12 +29,9 @@ enum PathEnv
|
||||
POSIX
|
||||
}
|
||||
|
||||
fn Path! new_cwd(Allocator allocator = allocator::heap())
|
||||
fn Path! new_cwd(Allocator allocator = allocator::heap()) => @pool(allocator)
|
||||
{
|
||||
@pool(allocator)
|
||||
{
|
||||
return new(os::getcwd(allocator::temp()), allocator);
|
||||
};
|
||||
return new(os::getcwd(allocator::temp()), allocator);
|
||||
}
|
||||
|
||||
fn Path! getcwd(Allocator allocator = allocator::heap()) @deprecated("Use new_cwd()")
|
||||
@@ -164,12 +161,9 @@ fn Path! temp_new(String path, PathEnv path_env = DEFAULT_PATH_ENV)
|
||||
return new(path, allocator::temp(), path_env);
|
||||
}
|
||||
|
||||
fn Path! new_win32_wstring(WString path, Allocator allocator = allocator::heap())
|
||||
fn Path! new_win32_wstring(WString path, Allocator allocator = allocator::heap()) => @pool(allocator)
|
||||
{
|
||||
@pool(allocator)
|
||||
{
|
||||
return path::new(string::temp_from_wstring(path)!, allocator: allocator);
|
||||
};
|
||||
return path::new(string::temp_from_wstring(path)!, allocator: allocator);
|
||||
}
|
||||
|
||||
fn Path! new_windows(String path, Allocator allocator = allocator::heap())
|
||||
|
||||
@@ -257,16 +257,13 @@ fn bool InetAddress.is_multicast_link_local(InetAddress* addr)
|
||||
return addr.ipv4.a == 224 && addr.ipv4.b == 0 && addr.ipv4.c == 0;
|
||||
}
|
||||
|
||||
fn AddrInfo*! addrinfo(String host, uint port, AIFamily ai_family, AISockType ai_socktype) @if(os::SUPPORTS_INET)
|
||||
fn AddrInfo*! addrinfo(String host, uint port, AIFamily ai_family, AISockType ai_socktype) @if(os::SUPPORTS_INET) => @pool()
|
||||
{
|
||||
@pool()
|
||||
{
|
||||
ZString zhost = host.zstr_tcopy();
|
||||
DString str = dstring::temp_with_capacity(32);
|
||||
str.appendf("%d", port);
|
||||
AddrInfo hints = { .ai_family = ai_family, .ai_socktype = ai_socktype };
|
||||
AddrInfo* ai;
|
||||
if (os::getaddrinfo(zhost, str.zstr_view(), &hints, &ai)) return NetError.ADDRINFO_FAILED?;
|
||||
return ai;
|
||||
};
|
||||
ZString zhost = host.zstr_tcopy();
|
||||
DString str = dstring::temp_with_capacity(32);
|
||||
str.appendf("%d", port);
|
||||
AddrInfo hints = { .ai_family = ai_family, .ai_socktype = ai_socktype };
|
||||
AddrInfo* ai;
|
||||
if (os::getaddrinfo(zhost, str.zstr_view(), &hints, &ai)) return NetError.ADDRINFO_FAILED?;
|
||||
return ai;
|
||||
}
|
||||
|
||||
@@ -177,70 +177,67 @@ fn Url! new_parse(String url_string, Allocator allocator = allocator::heap())
|
||||
@param [inout] allocator
|
||||
@return "Url as a string"
|
||||
*>
|
||||
fn String Url.to_string(&self, Allocator allocator = allocator::heap()) @dynamic
|
||||
fn String Url.to_string(&self, Allocator allocator = allocator::heap()) @dynamic => @pool(allocator)
|
||||
{
|
||||
@pool(allocator)
|
||||
DString builder = dstring::temp_new();
|
||||
|
||||
// Add scheme if it exists
|
||||
if (self.scheme != "")
|
||||
{
|
||||
DString builder = dstring::temp_new();
|
||||
builder.append_chars(self.scheme);
|
||||
builder.append_char(':');
|
||||
if (self.host.len > 0) builder.append_chars("//");
|
||||
}
|
||||
|
||||
// Add scheme if it exists
|
||||
if (self.scheme != "")
|
||||
{
|
||||
builder.append_chars(self.scheme);
|
||||
builder.append_char(':');
|
||||
if (self.host.len > 0) builder.append_chars("//");
|
||||
}
|
||||
// Add username and password if they exist
|
||||
if (self.username != "")
|
||||
{
|
||||
String username = temp_encode(self.username, USERPASS);
|
||||
builder.append_chars(username);
|
||||
|
||||
// Add username and password if they exist
|
||||
if (self.username != "")
|
||||
{
|
||||
String username = temp_encode(self.username, USERPASS);
|
||||
builder.append_chars(username);
|
||||
|
||||
if (self.password != "")
|
||||
{
|
||||
builder.append_char(':');
|
||||
|
||||
String password = temp_encode(self.password, USERPASS);
|
||||
builder.append_chars(password);
|
||||
}
|
||||
builder.append_char('@');
|
||||
}
|
||||
|
||||
// Add host
|
||||
String host = temp_encode(self.host, HOST);
|
||||
builder.append_chars(host);
|
||||
|
||||
// Add port
|
||||
if (self.port != 0)
|
||||
if (self.password != "")
|
||||
{
|
||||
builder.append_char(':');
|
||||
builder.appendf("%d", self.port);
|
||||
|
||||
String password = temp_encode(self.password, USERPASS);
|
||||
builder.append_chars(password);
|
||||
}
|
||||
builder.append_char('@');
|
||||
}
|
||||
|
||||
// Add path
|
||||
String path = temp_encode(self.path, PATH);
|
||||
builder.append_chars(path);
|
||||
// Add host
|
||||
String host = temp_encode(self.host, HOST);
|
||||
builder.append_chars(host);
|
||||
|
||||
// Add query if it exists (note that `query` is expected to
|
||||
// be already properly encoded).
|
||||
if (self.query != "")
|
||||
{
|
||||
builder.append_char('?');
|
||||
builder.append_chars(self.query);
|
||||
}
|
||||
// Add port
|
||||
if (self.port != 0)
|
||||
{
|
||||
builder.append_char(':');
|
||||
builder.appendf("%d", self.port);
|
||||
}
|
||||
|
||||
// Add fragment if it exists
|
||||
if (self.fragment != "")
|
||||
{
|
||||
builder.append_char('#');
|
||||
// Add path
|
||||
String path = temp_encode(self.path, PATH);
|
||||
builder.append_chars(path);
|
||||
|
||||
String fragment = temp_encode(self.fragment, FRAGMENT);
|
||||
builder.append_chars(fragment);
|
||||
}
|
||||
// Add query if it exists (note that `query` is expected to
|
||||
// be already properly encoded).
|
||||
if (self.query != "")
|
||||
{
|
||||
builder.append_char('?');
|
||||
builder.append_chars(self.query);
|
||||
}
|
||||
|
||||
return builder.copy_str(allocator);
|
||||
};
|
||||
// Add fragment if it exists
|
||||
if (self.fragment != "")
|
||||
{
|
||||
builder.append_char('#');
|
||||
|
||||
String fragment = temp_encode(self.fragment, FRAGMENT);
|
||||
builder.append_chars(fragment);
|
||||
}
|
||||
|
||||
return builder.copy_str(allocator);
|
||||
}
|
||||
|
||||
def UrlQueryValueList = List<[String]>;
|
||||
@@ -327,35 +324,32 @@ fn UrlQueryValues* UrlQueryValues.add(&self, String key, String value)
|
||||
@param [inout] allocator
|
||||
@return "a percent-encoded query string"
|
||||
*>
|
||||
fn String UrlQueryValues.to_string(&self, Allocator allocator = allocator::heap()) @dynamic
|
||||
fn String UrlQueryValues.to_string(&self, Allocator allocator = allocator::heap()) @dynamic => @pool(allocator)
|
||||
{
|
||||
@pool(allocator)
|
||||
DString builder = dstring::temp_new();
|
||||
|
||||
usz i;
|
||||
foreach (key: self.key_order)
|
||||
{
|
||||
DString builder = dstring::temp_new();
|
||||
String encoded_key = temp_encode(key, QUERY);
|
||||
|
||||
usz i;
|
||||
foreach (key: self.key_order)
|
||||
UrlQueryValueList! values = self.map.get(key);
|
||||
if (catch values) continue;
|
||||
|
||||
foreach (value: values)
|
||||
{
|
||||
String encoded_key = temp_encode(key, QUERY);
|
||||
if (i > 0) builder.append_char('&');
|
||||
|
||||
UrlQueryValueList! values = self.map.get(key);
|
||||
if (catch values) continue;
|
||||
builder.append_chars(encoded_key);
|
||||
builder.append_char('=');
|
||||
|
||||
foreach (value: values)
|
||||
{
|
||||
if (i > 0) builder.append_char('&');
|
||||
|
||||
builder.append_chars(encoded_key);
|
||||
builder.append_char('=');
|
||||
|
||||
String encoded_value = temp_encode(value, QUERY);
|
||||
builder.append_chars(encoded_value);
|
||||
i++;
|
||||
}
|
||||
};
|
||||
|
||||
return builder.copy_str(allocator);
|
||||
String encoded_value = temp_encode(value, QUERY);
|
||||
builder.append_chars(encoded_value);
|
||||
i++;
|
||||
}
|
||||
};
|
||||
|
||||
return builder.copy_str(allocator);
|
||||
}
|
||||
|
||||
fn void UrlQueryValues.free(&self)
|
||||
|
||||
@@ -67,35 +67,32 @@ fn usz encode_len(String s, UrlEncodingMode mode) @inline
|
||||
@param [inout] allocator
|
||||
@return "Percent-encoded String"
|
||||
*>
|
||||
fn String encode(String s, UrlEncodingMode mode, Allocator allocator)
|
||||
fn String encode(String s, UrlEncodingMode mode, Allocator allocator) => @pool(allocator)
|
||||
{
|
||||
usz n = encode_len(s, mode);
|
||||
@pool(allocator)
|
||||
DString builder = dstring::temp_with_capacity(n);
|
||||
|
||||
foreach(i, c: s)
|
||||
{
|
||||
DString builder = dstring::temp_with_capacity(n);
|
||||
|
||||
foreach(i, c: s)
|
||||
switch
|
||||
{
|
||||
switch
|
||||
{
|
||||
// encode spaces in queries
|
||||
case c == ' ' && mode == QUERY:
|
||||
builder.append_char('+');
|
||||
// encode spaces in queries
|
||||
case c == ' ' && mode == QUERY:
|
||||
builder.append_char('+');
|
||||
|
||||
// add encoded char
|
||||
case should_encode(c, mode):
|
||||
builder.append_char('%');
|
||||
String hex = hex::encode_temp(s[i:1]);
|
||||
builder.append(hex.temp_ascii_to_upper());
|
||||
// add encoded char
|
||||
case should_encode(c, mode):
|
||||
builder.append_char('%');
|
||||
String hex = hex::encode_temp(s[i:1]);
|
||||
builder.append(hex.temp_ascii_to_upper());
|
||||
|
||||
// use char, no encoding needed
|
||||
default:
|
||||
builder.append_char(c);
|
||||
}
|
||||
// use char, no encoding needed
|
||||
default:
|
||||
builder.append_char(c);
|
||||
}
|
||||
}
|
||||
|
||||
return builder.copy_str(allocator);
|
||||
};
|
||||
return builder.copy_str(allocator);
|
||||
}
|
||||
|
||||
<*
|
||||
@@ -146,35 +143,32 @@ fn usz! decode_len(String s, UrlEncodingMode mode) @inline
|
||||
@param [inout] allocator
|
||||
@return "Percent-decoded String"
|
||||
*>
|
||||
fn String! decode(String s, UrlEncodingMode mode, Allocator allocator)
|
||||
fn String! decode(String s, UrlEncodingMode mode, Allocator allocator) => @pool(allocator)
|
||||
{
|
||||
usz n = decode_len(s, mode)!;
|
||||
@pool(allocator)
|
||||
DString builder = dstring::temp_with_capacity(n);
|
||||
|
||||
for (usz i = 0; i < s.len; i++)
|
||||
{
|
||||
DString builder = dstring::temp_with_capacity(n);
|
||||
|
||||
for (usz i = 0; i < s.len; i++)
|
||||
switch (s[i])
|
||||
{
|
||||
switch (s[i])
|
||||
{
|
||||
// decode encoded char
|
||||
case '%':
|
||||
char[] hex = hex::decode_temp(s[i+1:2])!;
|
||||
builder.append(hex);
|
||||
i += 2;
|
||||
// decode encoded char
|
||||
case '%':
|
||||
char[] hex = hex::decode_temp(s[i+1:2])!;
|
||||
builder.append(hex);
|
||||
i += 2;
|
||||
|
||||
// decode space when in queries
|
||||
case '+':
|
||||
builder.append_char((mode == QUERY) ? ' ' : '+');
|
||||
// decode space when in queries
|
||||
case '+':
|
||||
builder.append_char((mode == QUERY) ? ' ' : '+');
|
||||
|
||||
// use char, no decoding needed
|
||||
default:
|
||||
builder.append_char(s[i]);
|
||||
}
|
||||
// use char, no decoding needed
|
||||
default:
|
||||
builder.append_char(s[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return builder.copy_str(allocator);
|
||||
};
|
||||
return builder.copy_str(allocator);
|
||||
}
|
||||
|
||||
<*
|
||||
|
||||
@@ -9,10 +9,9 @@ import std::io::path, libc, std::os;
|
||||
@require name.len > 0
|
||||
@return! SearchResult.MISSING
|
||||
*>
|
||||
fn String! get_var(String name, Allocator allocator = allocator::heap())
|
||||
fn String! get_var(String name, Allocator allocator = allocator::heap()) => @pool(allocator)
|
||||
{
|
||||
@pool(allocator)
|
||||
{
|
||||
|
||||
$switch
|
||||
$case env::LIBC && !env::WIN32:
|
||||
ZString val = libc::getenv(name.zstr_tcopy());
|
||||
@@ -33,7 +32,6 @@ fn String! get_var(String name, Allocator allocator = allocator::heap())
|
||||
$default:
|
||||
return "";
|
||||
$endswitch
|
||||
};
|
||||
}
|
||||
|
||||
fn String! get_var_temp(String name)
|
||||
@@ -46,10 +44,8 @@ fn String! get_var_temp(String name)
|
||||
@param [in] value
|
||||
@require name.len > 0
|
||||
*>
|
||||
fn bool set_var(String name, String value, bool overwrite = true)
|
||||
fn bool set_var(String name, String value, bool overwrite = true) => @pool()
|
||||
{
|
||||
@pool()
|
||||
{
|
||||
$switch
|
||||
$case env::WIN32:
|
||||
WString wname = name.to_temp_wstring()!!;
|
||||
@@ -65,8 +61,6 @@ fn bool set_var(String name, String value, bool overwrite = true)
|
||||
$default:
|
||||
return false;
|
||||
$endswitch
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
<*
|
||||
@@ -91,10 +85,8 @@ fn Path! get_config_dir(Allocator allocator = allocator::heap()) @deprecated("us
|
||||
<*
|
||||
Returns the current user's config directory.
|
||||
*>
|
||||
fn Path! new_get_config_dir(Allocator allocator = allocator::heap())
|
||||
fn Path! new_get_config_dir(Allocator allocator = allocator::heap()) => @pool(allocator)
|
||||
{
|
||||
@pool(allocator)
|
||||
{
|
||||
$if env::WIN32:
|
||||
return path::new(get_var_temp("AppData"), allocator);
|
||||
$else
|
||||
@@ -107,7 +99,6 @@ fn Path! new_get_config_dir(Allocator allocator = allocator::heap())
|
||||
$endif
|
||||
return path::temp_new(s).new_append(DIR, allocator: allocator);
|
||||
$endif
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -115,10 +106,8 @@ fn Path! new_get_config_dir(Allocator allocator = allocator::heap())
|
||||
@param [in] name
|
||||
@require name.len > 0
|
||||
*>
|
||||
fn bool clear_var(String name)
|
||||
fn bool clear_var(String name) => @pool()
|
||||
{
|
||||
@pool()
|
||||
{
|
||||
$switch
|
||||
$case env::WIN32:
|
||||
WString wname = name.to_temp_wstring()!!;
|
||||
@@ -128,7 +117,6 @@ fn bool clear_var(String name)
|
||||
$default:
|
||||
return false;
|
||||
$endswitch
|
||||
};
|
||||
}
|
||||
|
||||
fn String! executable_path(Allocator allocator = allocator::heap()) @deprecated("use new_executable_path()")
|
||||
|
||||
@@ -204,7 +204,8 @@ fn void! backtrace_add_element(BacktraceList *list, void* addr, Allocator alloca
|
||||
return;
|
||||
}
|
||||
|
||||
@pool(allocator) {
|
||||
@pool(allocator)
|
||||
{
|
||||
Linux_Dl_info info;
|
||||
if (dladdr(addr, &info) == 0)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user