Do not link with debug libc on win32 when using cross compile libs. Add delete methods to dstring. Fixes to macOS aarch64 codegen. Use glibc backtrace when available. Add load_* methods to file. The cast (int[8])int_slice[:8] now works.

This commit is contained in:
Christoffer Lerno
2023-11-27 11:18:42 +01:00
committed by Christoffer Lerno
parent a50c5f4f7c
commit 1d61ace302
25 changed files with 312 additions and 20 deletions

View File

@@ -280,6 +280,37 @@ fn void DString.append_char(&self, char c)
data.chars[data.len++] = c;
}
/**
* @require start < self.len()
* @require end < self.len()
* @require end >= start "End must be same or equal to the start"
**/
fn void DString.delete_range(&self, usz start, usz end)
{
self.delete(start, end - start + 1);
}
/**
* @require start < self.len()
* @require start + len <= self.len()
**/
fn void DString.delete(&self, usz start, usz len = 1)
{
if (!len) return;
StringData* data = self.data();
usz new_len = data.len - len;
if (new_len == 0)
{
data.len = 0;
return;
}
usz len_after = data.len - start - len;
if (len_after > 0)
{
data.chars[start:len_after] = data.chars[start + len:len_after];
}
data.len = new_len;
}
macro void DString.append(&self, value)
{

View File

@@ -444,6 +444,11 @@ fn String String.new_ascii_to_upper(s, Allocator* allocator = mem::heap())
return copy;
}
fn StringIterator String.iterator(s)
{
return { s, 0 };
}
fn String String.temp_ascii_to_upper(s)
{
return s.new_ascii_to_upper(mem::temp());
@@ -575,3 +580,38 @@ fn char! String.to_uchar(s) => s.to_integer(char);
fn double! String.to_double(s) => s.to_real(double);
fn float! String.to_float(s) => s.to_real(float);
fn Splitter String.splitter(self, String split)
{
return Splitter { self, split, 0 };
}
struct Splitter
{
String string;
String split;
usz current;
}
fn void Splitter.reset(&self)
{
self.current = 0;
}
fn String! Splitter.next(&self)
{
usz len = self.string.len;
usz current = self.current;
if (current >= len) return IteratorResult.NO_MORE_ELEMENT?;
String remaining = self.string[current..];
usz! next = remaining.index_of(self.split);
if (try next)
{
defer self.current = current + next + self.split.len;
return remaining[:next];
}
self.current = len;
return remaining;
}

View File

@@ -20,4 +20,4 @@ fn Char32! StringIterator.next(&self)
Char32 res = conv::utf8_to_char32(&self.utf8[current], &read)!;
self.current += read;
return res;
}
}

View File

@@ -138,6 +138,50 @@ fn char! File.read_byte(&self) @dynamic
return (char)c;
}
/**
* Load up to buffer.len characters. Returns IoError.OVERFLOW if the file is longer
* than the buffer.
*
* @param filename "The path to the file to read"
* @param [in] buffer "The buffer to read to"
**/
fn char[]! load_buffer(String filename, char[] buffer)
{
File file = open(filename, "rb")!;
defer (void)file.close();
usz len = file.seek(0, END)!;
if (len > buffer.len) return IoError.OVERFLOW?;
file.seek(0, SET)!;
usz read = 0;
while (read < len)
{
read += file.read(buffer[read:len - read])!;
}
return buffer[:len];
}
fn char[]! load_new(String filename, Allocator* allocator = mem::heap())
{
File file = open(filename, "rb")!;
defer (void)file.close();
usz len = file.seek(0, END)!;
file.seek(0, SET)!;
char* data = allocator.alloc_checked(len)!;
defer catch allocator.free(data);
usz read = 0;
while (read < len)
{
read += file.read(data[read:len - read])!;
}
return data[:len];
}
fn char[]! load_temp(String filename)
{
return load_new(filename, mem::temp());
}
/**
* @require self.file `File must be initialized`
*/

View File

@@ -49,7 +49,7 @@ fault IoError
* @param stream
* @require @is_instream(stream)
**/
macro String! readline(stream = io::stdin(), Allocator* allocator = mem::heap())
macro String! readline(stream = io::stdin(), Allocator* allocator = mem::heap())
{
bool $is_stream = @typeid(stream) == InStream*.typeid;
$if $is_stream:

View File

@@ -1,5 +1,15 @@
module libc @if(env::POSIX);
extern fn void* dlopen(ZString path, int flags);
extern fn CInt dlclose(void*);
extern fn void* dlsym(void* handle, ZString symbol);
const int RTLD_LAZY = 0x1;
const int RTLD_NOW = 0x2;
const int RTLD_LOCAL = 0x4;
const int RTLD_GLOBAL = 0x8;
def Pid_t = int;
def Uid_t = uint;
def Gid_t = uint;

View File

@@ -56,10 +56,21 @@ const CInt WNOHANG = 1;
const CInt WUNTRACES = 2;
JmpBuf backtrace_jmpbuf @local;
fn CInt backtrace(void** buffer, CInt size) @extern("backtrace") @weak
def BacktraceFn = fn CInt(void** buffer, CInt size);
fn CInt backtrace(void** buffer, CInt size)
{
if (size < 1) return 0;
void* handle = libc::dlopen("libc.so.6", libc::RTLD_LAZY);
if (handle)
{
BacktraceFn backtrace_fn = libc::dlsym(handle, "backtrace");
libc::dlclose(handle);
if (backtrace_fn)
{
return backtrace_fn(buffer, size);
}
}
// Loop through the return addresses until we hit a signal.
// This avoids using the frame address.
SignalFunction restore_backtrace = fn void(CInt) {