mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
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:
committed by
Christoffer Lerno
parent
a50c5f4f7c
commit
1d61ace302
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -20,4 +20,4 @@ fn Char32! StringIterator.next(&self)
|
||||
Char32 res = conv::utf8_to_char32(&self.utf8[current], &read)!;
|
||||
self.current += read;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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`
|
||||
*/
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user