mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
- Create optional with ~ instead of ?. return io::EOF?; becomes return io::EOF~.
- Deprecated use of `?` to create optional.
This commit is contained in:
@@ -368,7 +368,7 @@ fn usz? ElasticArray.index_of(&self, Type type) @if(ELEMENT_IS_EQUATABLE)
|
||||
{
|
||||
if (equals(v, type)) return i;
|
||||
}
|
||||
return NOT_FOUND?;
|
||||
return NOT_FOUND~;
|
||||
}
|
||||
|
||||
fn usz? ElasticArray.rindex_of(&self, Type type) @if(ELEMENT_IS_EQUATABLE)
|
||||
@@ -377,7 +377,7 @@ fn usz? ElasticArray.rindex_of(&self, Type type) @if(ELEMENT_IS_EQUATABLE)
|
||||
{
|
||||
if (equals(v, type)) return i;
|
||||
}
|
||||
return NOT_FOUND?;
|
||||
return NOT_FOUND~;
|
||||
}
|
||||
|
||||
fn bool ElasticArray.equals(&self, ElasticArray other_list) @if(ELEMENT_IS_EQUATABLE)
|
||||
|
||||
@@ -175,13 +175,13 @@ fn usz HashMap.len(&map) @inline
|
||||
|
||||
fn Value*? HashMap.get_ref(&map, Key key)
|
||||
{
|
||||
if (!map.count) return NOT_FOUND?;
|
||||
if (!map.count) return NOT_FOUND~;
|
||||
uint hash = rehash(key.hash());
|
||||
for (Entry *e = map.table[index_for(hash, map.table.len)]; e != null; e = e.next)
|
||||
{
|
||||
if (e.hash == hash && equals(key, e.key)) return &e.value;
|
||||
}
|
||||
return NOT_FOUND?;
|
||||
return NOT_FOUND~;
|
||||
}
|
||||
|
||||
fn Value* HashMap.get_or_create_ref(&map, Key key) @operator(&[])
|
||||
@@ -204,13 +204,13 @@ fn Value* HashMap.get_or_create_ref(&map, Key key) @operator(&[])
|
||||
|
||||
fn Entry*? HashMap.get_entry(&map, Key key)
|
||||
{
|
||||
if (!map.count) return NOT_FOUND?;
|
||||
if (!map.count) return NOT_FOUND~;
|
||||
uint hash = rehash(key.hash());
|
||||
for (Entry *e = map.table[index_for(hash, map.table.len)]; e != null; e = e.next)
|
||||
{
|
||||
if (e.hash == hash && equals(key, e.key)) return e;
|
||||
}
|
||||
return NOT_FOUND?;
|
||||
return NOT_FOUND~;
|
||||
}
|
||||
|
||||
<*
|
||||
@@ -275,7 +275,7 @@ fn bool HashMap.set(&map, Key key, Value value) @operator([]=)
|
||||
|
||||
fn void? HashMap.remove(&map, Key key) @maydiscard
|
||||
{
|
||||
if (!map.remove_entry_for_key(key)) return NOT_FOUND?;
|
||||
if (!map.remove_entry_for_key(key)) return NOT_FOUND~;
|
||||
}
|
||||
|
||||
fn void HashMap.clear(&map)
|
||||
|
||||
@@ -258,7 +258,7 @@ fn bool HashSet.contains(&set, Value value)
|
||||
*>
|
||||
fn void? HashSet.remove(&set, Value value) @maydiscard
|
||||
{
|
||||
if (!set.remove_entry_for_value(value)) return NOT_FOUND?;
|
||||
if (!set.remove_entry_for_value(value)) return NOT_FOUND~;
|
||||
}
|
||||
|
||||
fn usz HashSet.remove_all(&set, Value[] values)
|
||||
@@ -634,7 +634,7 @@ fn Value? HashSetIterator.next(&self)
|
||||
}
|
||||
}
|
||||
|
||||
return NOT_FOUND?;
|
||||
return NOT_FOUND~;
|
||||
}
|
||||
|
||||
fn usz HashSetIterator.len(&self) @operator(len)
|
||||
|
||||
@@ -93,7 +93,7 @@ fn void InterfaceList.free_element(&self, Type element) @inline
|
||||
*>
|
||||
fn Type? InterfaceList.copy_pop(&self, Allocator allocator)
|
||||
{
|
||||
if (!self.size) return NO_MORE_ELEMENT?;
|
||||
if (!self.size) return NO_MORE_ELEMENT~;
|
||||
defer self.free_element(self.entries[self.size]);
|
||||
return (Type)allocator::clone_any(allocator, self.entries[--self.size]);
|
||||
}
|
||||
@@ -114,7 +114,7 @@ fn Type? InterfaceList.tcopy_pop(&self) => self.copy_pop(tmem);
|
||||
*>
|
||||
fn Type? InterfaceList.pop_retained(&self)
|
||||
{
|
||||
if (!self.size) return NO_MORE_ELEMENT?;
|
||||
if (!self.size) return NO_MORE_ELEMENT~;
|
||||
return self.entries[--self.size];
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ fn void InterfaceList.clear(&self)
|
||||
*>
|
||||
fn Type? InterfaceList.pop_first_retained(&self)
|
||||
{
|
||||
if (!self.size) return NO_MORE_ELEMENT?;
|
||||
if (!self.size) return NO_MORE_ELEMENT~;
|
||||
defer self.remove_at(0);
|
||||
return self.entries[0];
|
||||
}
|
||||
@@ -152,7 +152,7 @@ fn Type? InterfaceList.pop_first_retained(&self)
|
||||
*>
|
||||
fn Type? InterfaceList.copy_pop_first(&self, Allocator allocator)
|
||||
{
|
||||
if (!self.size) return NO_MORE_ELEMENT?;
|
||||
if (!self.size) return NO_MORE_ELEMENT~;
|
||||
defer self.free_element(self.entries[self.size]);
|
||||
defer self.remove_at(0);
|
||||
return (Type)allocator::clone_any(allocator, self.entries[0]);
|
||||
@@ -276,7 +276,7 @@ fn void InterfaceList.remove_first(&self)
|
||||
*>
|
||||
fn Type? InterfaceList.first(&self) @inline
|
||||
{
|
||||
return self.size ? self.entries[0] : NO_MORE_ELEMENT?;
|
||||
return self.size ? self.entries[0] : NO_MORE_ELEMENT~;
|
||||
}
|
||||
|
||||
<*
|
||||
@@ -287,7 +287,7 @@ fn Type? InterfaceList.first(&self) @inline
|
||||
*>
|
||||
fn Type? InterfaceList.last(&self) @inline
|
||||
{
|
||||
return self.size ? self.entries[self.size - 1] : NO_MORE_ELEMENT?;
|
||||
return self.size ? self.entries[self.size - 1] : NO_MORE_ELEMENT~;
|
||||
}
|
||||
|
||||
<*
|
||||
|
||||
@@ -178,7 +178,7 @@ fn Value? LinkedBlockingQueue.pop(&self)
|
||||
{
|
||||
self.lock.@in_lock()
|
||||
{
|
||||
if (self.count == 0) return NO_MORE_ELEMENT?;
|
||||
if (self.count == 0) return NO_MORE_ELEMENT~;
|
||||
|
||||
QueueEntry* entry = self.unlink_head();
|
||||
Value value = entry.value;
|
||||
@@ -214,7 +214,7 @@ fn Value? LinkedBlockingQueue.poll_timeout(&self, Duration timeout)
|
||||
if (end <= time::now()) break;
|
||||
if (catch self.not_empty.wait_until(&self.lock, end)) break;
|
||||
}
|
||||
if (!self.count) return NO_MORE_ELEMENT?;
|
||||
if (!self.count) return NO_MORE_ELEMENT~;
|
||||
}
|
||||
|
||||
QueueEntry* entry = self.unlink_head();
|
||||
@@ -266,7 +266,7 @@ fn void? LinkedBlockingQueue.try_push(&self, Value value)
|
||||
{
|
||||
self.lock.@in_lock()
|
||||
{
|
||||
if (self.capacity > 0 && self.count >= self.capacity) return CAPACITY_EXCEEDED?;
|
||||
if (self.capacity > 0 && self.count >= self.capacity) return CAPACITY_EXCEEDED~;
|
||||
|
||||
QueueEntry* entry = allocator::new(self.allocator, QueueEntry, {
|
||||
.value = value,
|
||||
@@ -299,7 +299,7 @@ fn void? LinkedBlockingQueue.push_timeout(&self, Value value, Duration timeout)
|
||||
if (end <= time::now()) break;
|
||||
if (catch self.not_empty.wait_until(&self.lock, end)) break;
|
||||
}
|
||||
if (self.capacity > 0 && self.count >= self.capacity) return CAPACITY_EXCEEDED?;
|
||||
if (self.capacity > 0 && self.count >= self.capacity) return CAPACITY_EXCEEDED~;
|
||||
}
|
||||
|
||||
QueueEntry* entry = allocator::new(self.allocator, QueueEntry, {
|
||||
@@ -314,13 +314,13 @@ fn void? LinkedBlockingQueue.push_timeout(&self, Value value, Duration timeout)
|
||||
|
||||
<*
|
||||
@require self.is_initialized() : "Queue must be initialized"
|
||||
@return "The head value or NO_MORE_ELEMENT? if queue is empty"
|
||||
@return "The head value or NO_MORE_ELEMENT~ if queue is empty"
|
||||
*>
|
||||
fn Value? LinkedBlockingQueue.peek(&self)
|
||||
{
|
||||
self.lock.@in_lock()
|
||||
{
|
||||
return (self.head != null) ? self.head.value : NO_MORE_ELEMENT?;
|
||||
return (self.head != null) ? self.head.value : NO_MORE_ELEMENT~;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -172,24 +172,24 @@ fn usz LinkedHashMap.len(&map) @inline => map.count;
|
||||
|
||||
fn Value*? LinkedHashMap.get_ref(&map, Key key)
|
||||
{
|
||||
if (!map.count) return NOT_FOUND?;
|
||||
if (!map.count) return NOT_FOUND~;
|
||||
uint hash = rehash(key.hash());
|
||||
for (LinkedEntry *e = map.table[index_for(hash, map.table.len)]; e != null; e = e.next)
|
||||
{
|
||||
if (e.hash == hash && equals(key, e.key)) return &e.value;
|
||||
}
|
||||
return NOT_FOUND?;
|
||||
return NOT_FOUND~;
|
||||
}
|
||||
|
||||
fn LinkedEntry*? LinkedHashMap.get_entry(&map, Key key)
|
||||
{
|
||||
if (!map.count) return NOT_FOUND?;
|
||||
if (!map.count) return NOT_FOUND~;
|
||||
uint hash = rehash(key.hash());
|
||||
for (LinkedEntry *e = map.table[index_for(hash, map.table.len)]; e != null; e = e.next)
|
||||
{
|
||||
if (e.hash == hash && equals(key, e.key)) return e;
|
||||
}
|
||||
return NOT_FOUND?;
|
||||
return NOT_FOUND~;
|
||||
}
|
||||
|
||||
<*
|
||||
@@ -248,7 +248,7 @@ fn bool LinkedHashMap.set(&map, Key key, Value value) @operator([]=)
|
||||
|
||||
fn void? LinkedHashMap.remove(&map, Key key) @maydiscard
|
||||
{
|
||||
if (!map.remove_entry_for_key(key)) return NOT_FOUND?;
|
||||
if (!map.remove_entry_for_key(key)) return NOT_FOUND~;
|
||||
}
|
||||
|
||||
fn void LinkedHashMap.clear(&map)
|
||||
@@ -375,17 +375,17 @@ fn bool LinkedHashMapIterator.next(&self)
|
||||
|
||||
fn LinkedEntry*? LinkedHashMapIterator.get(&self)
|
||||
{
|
||||
return self.current ? self.current : NOT_FOUND?;
|
||||
return self.current ? self.current : NOT_FOUND~;
|
||||
}
|
||||
|
||||
fn Value*? LinkedHashMapValueIterator.get(&self)
|
||||
{
|
||||
return self.current ? &self.current.value : NOT_FOUND?;
|
||||
return self.current ? &self.current.value : NOT_FOUND~;
|
||||
}
|
||||
|
||||
fn Key*? LinkedHashMapKeyIterator.get(&self)
|
||||
{
|
||||
return self.current ? &self.current.key : NOT_FOUND?;
|
||||
return self.current ? &self.current.key : NOT_FOUND~;
|
||||
}
|
||||
|
||||
fn bool LinkedHashMapIterator.has_next(&self)
|
||||
|
||||
@@ -266,7 +266,7 @@ fn bool LinkedHashSet.contains(&set, Value value)
|
||||
*>
|
||||
fn void? LinkedHashSet.remove(&set, Value value) @maydiscard
|
||||
{
|
||||
if (!set.remove_entry_for_value(value)) return NOT_FOUND?;
|
||||
if (!set.remove_entry_for_value(value)) return NOT_FOUND~;
|
||||
}
|
||||
|
||||
fn usz LinkedHashSet.remove_all(&set, Value[] values)
|
||||
@@ -713,7 +713,7 @@ fn bool LinkedHashSetIterator.next(&self)
|
||||
|
||||
fn Value*? LinkedHashSetIterator.get(&self)
|
||||
{
|
||||
return self.current ? &self.current.value : NOT_FOUND?;
|
||||
return self.current ? &self.current.value : NOT_FOUND~;
|
||||
}
|
||||
|
||||
fn bool LinkedHashSetIterator.has_next(&self)
|
||||
|
||||
@@ -124,13 +124,13 @@ fn Type? LinkedList.peek_last(&self) => self.last() @inline;
|
||||
|
||||
fn Type? LinkedList.first(&self)
|
||||
{
|
||||
if (!self._first) return NO_MORE_ELEMENT?;
|
||||
if (!self._first) return NO_MORE_ELEMENT~;
|
||||
return self._first.value;
|
||||
}
|
||||
|
||||
fn Type? LinkedList.last(&self)
|
||||
{
|
||||
if (!self._last) return NO_MORE_ELEMENT?;
|
||||
if (!self._last) return NO_MORE_ELEMENT~;
|
||||
return self._last.value;
|
||||
}
|
||||
|
||||
@@ -198,7 +198,7 @@ fn usz? LinkedList.index_of(&self, Type t) @if(ELEMENT_IS_EQUATABLE)
|
||||
{
|
||||
if (node.value == t) return i;
|
||||
}
|
||||
return NOT_FOUND?;
|
||||
return NOT_FOUND~;
|
||||
}
|
||||
|
||||
fn usz? LinkedList.rindex_of(&self, Type t) @if(ELEMENT_IS_EQUATABLE)
|
||||
@@ -208,7 +208,7 @@ fn usz? LinkedList.rindex_of(&self, Type t) @if(ELEMENT_IS_EQUATABLE)
|
||||
if (node.value == t) return i;
|
||||
if (i == 0) break;
|
||||
}
|
||||
return NOT_FOUND?;
|
||||
return NOT_FOUND~;
|
||||
}
|
||||
|
||||
|
||||
@@ -296,7 +296,7 @@ fn usz LinkedList.remove(&self, Type t) @if(ELEMENT_IS_EQUATABLE)
|
||||
|
||||
fn Type? LinkedList.pop(&self)
|
||||
{
|
||||
if (!self._last) return NO_MORE_ELEMENT?;
|
||||
if (!self._last) return NO_MORE_ELEMENT~;
|
||||
defer self.unlink_last();
|
||||
return self._last.value;
|
||||
}
|
||||
@@ -308,20 +308,20 @@ fn bool LinkedList.is_empty(&self)
|
||||
|
||||
fn Type? LinkedList.pop_front(&self)
|
||||
{
|
||||
if (!self._first) return NO_MORE_ELEMENT?;
|
||||
if (!self._first) return NO_MORE_ELEMENT~;
|
||||
defer self.unlink_first();
|
||||
return self._first.value;
|
||||
}
|
||||
|
||||
fn void? LinkedList.remove_last(&self) @maydiscard
|
||||
{
|
||||
if (!self._first) return NO_MORE_ELEMENT?;
|
||||
if (!self._first) return NO_MORE_ELEMENT~;
|
||||
self.unlink_last();
|
||||
}
|
||||
|
||||
fn void? LinkedList.remove_first(&self) @maydiscard
|
||||
{
|
||||
if (!self._first) return NO_MORE_ELEMENT?;
|
||||
if (!self._first) return NO_MORE_ELEMENT~;
|
||||
self.unlink_first();
|
||||
}
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ fn void List.push(&self, Type element) @inline
|
||||
|
||||
fn Type? List.pop(&self)
|
||||
{
|
||||
if (!self.size) return NO_MORE_ELEMENT?;
|
||||
if (!self.size) return NO_MORE_ELEMENT~;
|
||||
defer self.set_size(self.size - 1);
|
||||
return self.entries[self.size - 1];
|
||||
}
|
||||
@@ -127,7 +127,7 @@ fn void List.clear(&self)
|
||||
|
||||
fn Type? List.pop_first(&self)
|
||||
{
|
||||
if (!self.size) return NO_MORE_ELEMENT?;
|
||||
if (!self.size) return NO_MORE_ELEMENT~;
|
||||
defer self.remove_at(0);
|
||||
return self.entries[0];
|
||||
}
|
||||
@@ -250,25 +250,25 @@ fn void List.set_at(&self, usz index, Type type)
|
||||
|
||||
fn void? List.remove_last(&self) @maydiscard
|
||||
{
|
||||
if (!self.size) return NO_MORE_ELEMENT?;
|
||||
if (!self.size) return NO_MORE_ELEMENT~;
|
||||
self.set_size(self.size - 1);
|
||||
}
|
||||
|
||||
fn void? List.remove_first(&self) @maydiscard
|
||||
{
|
||||
if (!self.size) return NO_MORE_ELEMENT?;
|
||||
if (!self.size) return NO_MORE_ELEMENT~;
|
||||
self.remove_at(0);
|
||||
}
|
||||
|
||||
fn Type? List.first(&self)
|
||||
{
|
||||
if (!self.size) return NO_MORE_ELEMENT?;
|
||||
if (!self.size) return NO_MORE_ELEMENT~;
|
||||
return self.entries[0];
|
||||
}
|
||||
|
||||
fn Type? List.last(&self)
|
||||
{
|
||||
if (!self.size) return NO_MORE_ELEMENT?;
|
||||
if (!self.size) return NO_MORE_ELEMENT~;
|
||||
return self.entries[self.size - 1];
|
||||
}
|
||||
|
||||
@@ -467,7 +467,7 @@ fn usz? List.index_of(&self, Type type) @if (ELEMENT_IS_EQUATABLE)
|
||||
{
|
||||
if (equals(v, type)) return i;
|
||||
}
|
||||
return NOT_FOUND?;
|
||||
return NOT_FOUND~;
|
||||
}
|
||||
|
||||
fn usz? List.rindex_of(&self, Type type) @if (ELEMENT_IS_EQUATABLE)
|
||||
@@ -476,7 +476,7 @@ fn usz? List.rindex_of(&self, Type type) @if (ELEMENT_IS_EQUATABLE)
|
||||
{
|
||||
if (equals(v, type)) return i;
|
||||
}
|
||||
return NOT_FOUND?;
|
||||
return NOT_FOUND~;
|
||||
}
|
||||
|
||||
fn bool List.equals(&self, List other_list) @if(ELEMENT_IS_EQUATABLE)
|
||||
|
||||
@@ -32,7 +32,7 @@ const Maybe EMPTY = { };
|
||||
|
||||
macro Type? Maybe.get(self)
|
||||
{
|
||||
return self.has_value ? self.value : NOT_FOUND?;
|
||||
return self.has_value ? self.value : NOT_FOUND~;
|
||||
}
|
||||
|
||||
fn bool Maybe.equals(self, Maybe other) @operator(==) @if(types::is_equatable_type(Type))
|
||||
|
||||
@@ -400,7 +400,7 @@ macro String? Object.get_enum_at(&self, $EnumType, usz index)
|
||||
fn bool? Object.get_bool(&self, String key)
|
||||
{
|
||||
Object* value = self.get(key)!;
|
||||
if (!value.is_bool()) return TYPE_MISMATCH?;
|
||||
if (!value.is_bool()) return TYPE_MISMATCH~;
|
||||
return value.b;
|
||||
}
|
||||
|
||||
@@ -411,7 +411,7 @@ fn bool? Object.get_bool(&self, String key)
|
||||
fn bool? Object.get_bool_at(&self, usz index)
|
||||
{
|
||||
Object* value = self.get_at(index);
|
||||
if (!value.is_bool()) return TYPE_MISMATCH?;
|
||||
if (!value.is_bool()) return TYPE_MISMATCH~;
|
||||
return value.b;
|
||||
}
|
||||
|
||||
@@ -430,7 +430,7 @@ fn double? Object.get_float(&self, String key)
|
||||
case FLOAT:
|
||||
return value.f;
|
||||
default:
|
||||
return TYPE_MISMATCH?;
|
||||
return TYPE_MISMATCH~;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -449,7 +449,7 @@ fn double? Object.get_float_at(&self, usz index)
|
||||
case FLOAT:
|
||||
return value.f;
|
||||
default:
|
||||
return TYPE_MISMATCH?;
|
||||
return TYPE_MISMATCH~;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ fn Type? PrivatePriorityQueue.pop(&self)
|
||||
{
|
||||
usz i = 0;
|
||||
usz len = self.heap.len();
|
||||
if (!len) return NO_MORE_ELEMENT?;
|
||||
if (!len) return NO_MORE_ELEMENT~;
|
||||
usz new_count = len - 1;
|
||||
self.heap.swap(0, new_count);
|
||||
while OUTER: ((2 * i + 1) < new_count)
|
||||
|
||||
@@ -48,7 +48,7 @@ fn Element? RingBuffer.pop(&self)
|
||||
switch
|
||||
{
|
||||
case self.written == 0:
|
||||
return NO_MORE_ELEMENT?;
|
||||
return NO_MORE_ELEMENT~;
|
||||
case self.written < self.buf.len:
|
||||
self.written--;
|
||||
return self.buf[self.written];
|
||||
|
||||
@@ -100,7 +100,7 @@ fn usz? write(String filename, char[] input, QOIDesc* desc) => @pool()
|
||||
fn char[]? read(Allocator allocator, String filename, QOIDesc* desc, QOIChannels channels = AUTO) => @pool()
|
||||
{
|
||||
// read file
|
||||
char[] data = file::load_temp(filename) ?? FILE_OPEN_FAILED?!;
|
||||
char[] data = file::load_temp(filename) ?? FILE_OPEN_FAILED~!;
|
||||
// pass data to decode function
|
||||
return decode(allocator, data, desc, channels);
|
||||
}
|
||||
@@ -128,14 +128,14 @@ import std::bits;
|
||||
fn char[]? encode(Allocator allocator, char[] input, QOIDesc* desc) @nodiscard
|
||||
{
|
||||
// check info in desc
|
||||
if (desc.width == 0 || desc.height == 0) return INVALID_PARAMETERS?;
|
||||
if (desc.channels == AUTO) return INVALID_PARAMETERS?;
|
||||
if (desc.width == 0 || desc.height == 0) return INVALID_PARAMETERS~;
|
||||
if (desc.channels == AUTO) return INVALID_PARAMETERS~;
|
||||
uint pixels = desc.width * desc.height;
|
||||
if (pixels > PIXELS_MAX) return TOO_MANY_PIXELS?;
|
||||
if (pixels > PIXELS_MAX) return TOO_MANY_PIXELS~;
|
||||
|
||||
// check input data size
|
||||
uint image_size = pixels * desc.channels;
|
||||
if (image_size != input.len) return INVALID_DATA?;
|
||||
if (image_size != input.len) return INVALID_DATA~;
|
||||
|
||||
// allocate memory for encoded data (output)
|
||||
// header + chunk tag and RGB(A) data for each pixel + end of stream
|
||||
@@ -283,27 +283,27 @@ fn char[]? encode(Allocator allocator, char[] input, QOIDesc* desc) @nodiscard
|
||||
fn char[]? decode(Allocator allocator, char[] data, QOIDesc* desc, QOIChannels channels = AUTO) @nodiscard
|
||||
{
|
||||
// check input data
|
||||
if (data.len < Header.sizeof + END_OF_STREAM.len) return INVALID_DATA?;
|
||||
if (data.len < Header.sizeof + END_OF_STREAM.len) return INVALID_DATA~;
|
||||
|
||||
// get header
|
||||
Header* header = (Header*)data.ptr;
|
||||
|
||||
// check magic bytes (FourCC)
|
||||
if (bswap(header.be_magic) != 'qoif') return INVALID_DATA?;
|
||||
if (bswap(header.be_magic) != 'qoif') return INVALID_DATA~;
|
||||
|
||||
// copy header data to desc
|
||||
desc.width = bswap(header.be_width);
|
||||
desc.height = bswap(header.be_height);
|
||||
desc.channels = header.channels;
|
||||
desc.colorspace = header.colorspace;
|
||||
if (desc.channels == AUTO) return INVALID_DATA?; // Channels must be specified in the header
|
||||
if (desc.channels == AUTO) return INVALID_DATA~; // Channels must be specified in the header
|
||||
|
||||
// check width and height
|
||||
if (desc.width == 0 || desc.height == 0) return INVALID_DATA?;
|
||||
if (desc.width == 0 || desc.height == 0) return INVALID_DATA~;
|
||||
|
||||
// check pixel count
|
||||
ulong pixels = (ulong)desc.width * (ulong)desc.height;
|
||||
if (pixels > PIXELS_MAX) return TOO_MANY_PIXELS?;
|
||||
if (pixels > PIXELS_MAX) return TOO_MANY_PIXELS~;
|
||||
|
||||
uint pos = Header.sizeof; // Current position in data
|
||||
uint loc; // Current position in image (top-left corner)
|
||||
|
||||
@@ -90,12 +90,12 @@ fn void*? ArenaAllocator.acquire(&self, usz size, AllocInitType init_type, usz a
|
||||
{
|
||||
alignment = alignment_for_allocation(alignment);
|
||||
usz total_len = self.data.len;
|
||||
if (size > total_len) return mem::INVALID_ALLOC_SIZE?;
|
||||
if (size > total_len) return mem::INVALID_ALLOC_SIZE~;
|
||||
void* start_mem = self.data.ptr;
|
||||
void* unaligned_pointer_to_offset = start_mem + self.used + ArenaAllocatorHeader.sizeof;
|
||||
void* mem = mem::aligned_pointer(unaligned_pointer_to_offset, alignment);
|
||||
usz end = (usz)(mem - self.data.ptr) + size;
|
||||
if (end > total_len) return mem::OUT_OF_MEMORY?;
|
||||
if (end > total_len) return mem::OUT_OF_MEMORY~;
|
||||
self.used = end;
|
||||
ArenaAllocatorHeader* header = mem - ArenaAllocatorHeader.sizeof;
|
||||
header.size = size;
|
||||
@@ -117,7 +117,7 @@ fn void*? ArenaAllocator.resize(&self, void *old_pointer, usz size, usz alignmen
|
||||
alignment = alignment_for_allocation(alignment);
|
||||
assert(old_pointer >= self.data.ptr, "Pointer originates from a different allocator.");
|
||||
usz total_len = self.data.len;
|
||||
if (size > total_len) return mem::INVALID_ALLOC_SIZE?;
|
||||
if (size > total_len) return mem::INVALID_ALLOC_SIZE~;
|
||||
ArenaAllocatorHeader* header = old_pointer - ArenaAllocatorHeader.sizeof;
|
||||
usz old_size = header.size;
|
||||
// Do last allocation and alignment match?
|
||||
@@ -130,7 +130,7 @@ fn void*? ArenaAllocator.resize(&self, void *old_pointer, usz size, usz alignmen
|
||||
else
|
||||
{
|
||||
usz new_used = self.used + size - old_size;
|
||||
if (new_used > total_len) return mem::OUT_OF_MEMORY?;
|
||||
if (new_used > total_len) return mem::OUT_OF_MEMORY~;
|
||||
self.used = new_used;
|
||||
}
|
||||
header.size = size;
|
||||
|
||||
@@ -153,7 +153,7 @@ fn void*? DynamicArenaAllocator._alloc_new(&self, usz size, usz alignment) @loca
|
||||
if (catch err = page)
|
||||
{
|
||||
allocator::free(self.backing_allocator, mem);
|
||||
return err?;
|
||||
return err~;
|
||||
}
|
||||
page.memory = mem;
|
||||
void* mem_start = mem::aligned_pointer(mem + DynamicArenaChunk.sizeof, alignment);
|
||||
|
||||
@@ -23,22 +23,22 @@ fn void*? LibcAllocator.acquire(&self, usz bytes, AllocInitType init_type, usz a
|
||||
void* data @noinit;
|
||||
if (alignment > mem::DEFAULT_MEM_ALIGNMENT)
|
||||
{
|
||||
if (posix::posix_memalign(&data, alignment, bytes)) return mem::OUT_OF_MEMORY?;
|
||||
if (posix::posix_memalign(&data, alignment, bytes)) return mem::OUT_OF_MEMORY~;
|
||||
mem::clear(data, bytes, mem::DEFAULT_MEM_ALIGNMENT);
|
||||
return data;
|
||||
}
|
||||
return libc::calloc(1, bytes) ?: mem::OUT_OF_MEMORY?;
|
||||
return libc::calloc(1, bytes) ?: mem::OUT_OF_MEMORY~;
|
||||
}
|
||||
else
|
||||
{
|
||||
void* data @noinit;
|
||||
if (alignment > mem::DEFAULT_MEM_ALIGNMENT)
|
||||
{
|
||||
if (posix::posix_memalign(&data, alignment, bytes)) return mem::OUT_OF_MEMORY?;
|
||||
if (posix::posix_memalign(&data, alignment, bytes)) return mem::OUT_OF_MEMORY~;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(data = libc::malloc(bytes))) return mem::OUT_OF_MEMORY?;
|
||||
if (!(data = libc::malloc(bytes))) return mem::OUT_OF_MEMORY~;
|
||||
}
|
||||
$if env::TESTING:
|
||||
for (usz i = 0; i < bytes; i++) ((char*)data)[i] = 0xAA;
|
||||
@@ -49,9 +49,9 @@ fn void*? LibcAllocator.acquire(&self, usz bytes, AllocInitType init_type, usz a
|
||||
|
||||
fn void*? LibcAllocator.resize(&self, void* old_ptr, usz new_bytes, usz alignment) @dynamic
|
||||
{
|
||||
if (alignment <= mem::DEFAULT_MEM_ALIGNMENT) return libc::realloc(old_ptr, new_bytes) ?: mem::OUT_OF_MEMORY?;
|
||||
if (alignment <= mem::DEFAULT_MEM_ALIGNMENT) return libc::realloc(old_ptr, new_bytes) ?: mem::OUT_OF_MEMORY~;
|
||||
void* new_ptr;
|
||||
if (posix::posix_memalign(&new_ptr, alignment, new_bytes)) return mem::OUT_OF_MEMORY?;
|
||||
if (posix::posix_memalign(&new_ptr, alignment, new_bytes)) return mem::OUT_OF_MEMORY~;
|
||||
|
||||
$switch:
|
||||
$case env::DARWIN:
|
||||
@@ -83,12 +83,12 @@ fn void*? LibcAllocator.acquire(&self, usz bytes, AllocInitType init_type, usz a
|
||||
{
|
||||
if (alignment > 0)
|
||||
{
|
||||
return win32::_aligned_recalloc(null, 1, bytes, alignment) ?: mem::OUT_OF_MEMORY?;
|
||||
return win32::_aligned_recalloc(null, 1, bytes, alignment) ?: mem::OUT_OF_MEMORY~;
|
||||
}
|
||||
return libc::calloc(1, bytes) ?: mem::OUT_OF_MEMORY?;
|
||||
return libc::calloc(1, bytes) ?: mem::OUT_OF_MEMORY~;
|
||||
}
|
||||
void* data = alignment > 0 ? win32::_aligned_malloc(bytes, alignment) : libc::malloc(bytes);
|
||||
if (!data) return mem::OUT_OF_MEMORY?;
|
||||
if (!data) return mem::OUT_OF_MEMORY~;
|
||||
$if env::TESTING:
|
||||
for (usz i = 0; i < bytes; i++) ((char*)data)[i] = 0xAA;
|
||||
$endif
|
||||
@@ -99,9 +99,9 @@ fn void*? LibcAllocator.resize(&self, void* old_ptr, usz new_bytes, usz alignmen
|
||||
{
|
||||
if (alignment)
|
||||
{
|
||||
return win32::_aligned_realloc(old_ptr, new_bytes, alignment) ?: mem::OUT_OF_MEMORY?;
|
||||
return win32::_aligned_realloc(old_ptr, new_bytes, alignment) ?: mem::OUT_OF_MEMORY~;
|
||||
}
|
||||
return libc::realloc(old_ptr, new_bytes) ?: mem::OUT_OF_MEMORY?;
|
||||
return libc::realloc(old_ptr, new_bytes) ?: mem::OUT_OF_MEMORY~;
|
||||
}
|
||||
|
||||
fn void LibcAllocator.release(&self, void* old_ptr, bool aligned) @dynamic
|
||||
@@ -122,12 +122,12 @@ fn void*? LibcAllocator.acquire(&self, usz bytes, AllocInitType init_type, usz a
|
||||
if (init_type == ZERO)
|
||||
{
|
||||
void* data = alignment ? @aligned_alloc(fn void*(usz bytes) => libc::calloc(bytes, 1), bytes, alignment)!! : libc::calloc(bytes, 1);
|
||||
return data ?: mem::OUT_OF_MEMORY?;
|
||||
return data ?: mem::OUT_OF_MEMORY~;
|
||||
}
|
||||
else
|
||||
{
|
||||
void* data = alignment ? @aligned_alloc(libc::malloc, bytes, alignment)!! : libc::malloc(bytes);
|
||||
if (!data) return mem::OUT_OF_MEMORY?;
|
||||
if (!data) return mem::OUT_OF_MEMORY~;
|
||||
$if env::TESTING:
|
||||
for (usz i = 0; i < bytes; i++) ((char*)data)[i] = 0xAA;
|
||||
$endif
|
||||
@@ -141,9 +141,9 @@ fn void*? LibcAllocator.resize(&self, void* old_ptr, usz new_bytes, usz alignmen
|
||||
if (alignment)
|
||||
{
|
||||
void* data = @aligned_realloc(fn void*(usz bytes) => libc::malloc(bytes), libc::free, old_ptr, new_bytes, alignment)!!;
|
||||
return data ?: mem::OUT_OF_MEMORY?;
|
||||
return data ?: mem::OUT_OF_MEMORY~;
|
||||
}
|
||||
return libc::realloc(old_ptr, new_bytes) ?: mem::OUT_OF_MEMORY?;
|
||||
return libc::realloc(old_ptr, new_bytes) ?: mem::OUT_OF_MEMORY~;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ fn void? Vmem.init(&self, usz preferred_size, usz reserve_page_size = 0, VmemOpt
|
||||
if (page_size < reserve_page_size) page_size = reserve_page_size;
|
||||
preferred_size = mem::aligned_offset(preferred_size, page_size);
|
||||
if (!min_size) min_size = max(preferred_size / 1024, 1);
|
||||
VirtualMemory? memory = mem::OUT_OF_MEMORY?;
|
||||
VirtualMemory? memory = mem::OUT_OF_MEMORY~;
|
||||
while (preferred_size >= min_size)
|
||||
{
|
||||
memory = vm::virtual_alloc(preferred_size, PROTECTED);
|
||||
@@ -62,7 +62,7 @@ fn void? Vmem.init(&self, usz preferred_size, usz reserve_page_size = 0, VmemOpt
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (catch memory) return VMEM_RESERVE_FAILED?;
|
||||
if (catch memory) return VMEM_RESERVE_FAILED~;
|
||||
if (page_size > preferred_size) page_size = preferred_size;
|
||||
$if env::ADDRESS_SANITIZER:
|
||||
asan::poison_memory_region(memory.ptr, memory.size);
|
||||
@@ -87,12 +87,12 @@ fn void*? Vmem.acquire(&self, usz size, AllocInitType init_type, usz alignment)
|
||||
{
|
||||
alignment = alignment_for_allocation(alignment);
|
||||
usz total_len = self.memory.size;
|
||||
if (size > total_len) return mem::INVALID_ALLOC_SIZE?;
|
||||
if (size > total_len) return mem::INVALID_ALLOC_SIZE~;
|
||||
void* start_mem = self.memory.ptr;
|
||||
void* unaligned_pointer_to_offset = start_mem + self.allocated + VmemHeader.sizeof;
|
||||
void* mem = mem::aligned_pointer(unaligned_pointer_to_offset, alignment);
|
||||
usz after = (usz)(mem - start_mem) + size;
|
||||
if (after > total_len) return mem::OUT_OF_MEMORY?;
|
||||
if (after > total_len) return mem::OUT_OF_MEMORY~;
|
||||
if (init_type == ZERO && self.high_water <= self.allocated)
|
||||
{
|
||||
init_type = NO_ZERO;
|
||||
@@ -119,7 +119,7 @@ fn bool Vmem.owns_pointer(&self, void* ptr) @inline
|
||||
*>
|
||||
fn void*? Vmem.resize(&self, void *old_pointer, usz size, usz alignment) @dynamic
|
||||
{
|
||||
if (size > self.memory.size) return mem::INVALID_ALLOC_SIZE?;
|
||||
if (size > self.memory.size) return mem::INVALID_ALLOC_SIZE~;
|
||||
alignment = alignment_for_allocation(alignment);
|
||||
assert(self.owns_pointer(old_pointer), "Pointer originates from a different allocator: %p, not in %p - %p", old_pointer, self.memory.ptr, self.memory.ptr + self.allocated);
|
||||
VmemHeader* header = old_pointer - VmemHeader.sizeof;
|
||||
@@ -135,7 +135,7 @@ fn void*? Vmem.resize(&self, void *old_pointer, usz size, usz alignment) @dynami
|
||||
else
|
||||
{
|
||||
usz allocated = self.allocated + size - old_size;
|
||||
if (allocated > self.memory.size) return mem::OUT_OF_MEMORY?;
|
||||
if (allocated > self.memory.size) return mem::OUT_OF_MEMORY~;
|
||||
protect(self, allocated)!;
|
||||
}
|
||||
header.size = size;
|
||||
|
||||
@@ -35,7 +35,7 @@ macro usz? index_of(array, element)
|
||||
{
|
||||
if (*e == element) return i;
|
||||
}
|
||||
return NOT_FOUND?;
|
||||
return NOT_FOUND~;
|
||||
}
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ macro usz? rindex_of(array, element)
|
||||
{
|
||||
if (*e == element) return i;
|
||||
}
|
||||
return NOT_FOUND?;
|
||||
return NOT_FOUND~;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ macro bool @in(#needle, ...) @builtin @const
|
||||
*>
|
||||
macro anycast(any v, $Type) @builtin
|
||||
{
|
||||
if (v.type != $Type.typeid) return TYPE_MISMATCH?;
|
||||
if (v.type != $Type.typeid) return TYPE_MISMATCH~;
|
||||
return ($Type*)v.ptr;
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ macro anycast(any v, $Type) @builtin
|
||||
*>
|
||||
macro any.to(self, $Type)
|
||||
{
|
||||
if (self.type != $Type.typeid) return TYPE_MISMATCH?;
|
||||
if (self.type != $Type.typeid) return TYPE_MISMATCH~;
|
||||
return *($Type*)self.ptr;
|
||||
}
|
||||
|
||||
@@ -350,7 +350,7 @@ macro enum_by_name($Type, String enum_name) @builtin
|
||||
{
|
||||
if (name == enum_name) return $Type.from_ordinal(i);
|
||||
}
|
||||
return NOT_FOUND?;
|
||||
return NOT_FOUND~;
|
||||
}
|
||||
|
||||
<*
|
||||
@@ -367,7 +367,7 @@ macro @enum_from_value($Type, #value, value) @builtin @deprecated("Use Enum.look
|
||||
{
|
||||
if (e.#value == value) return e;
|
||||
}
|
||||
return NOT_FOUND?;
|
||||
return NOT_FOUND~;
|
||||
}
|
||||
|
||||
<*
|
||||
@@ -537,7 +537,7 @@ macro bool @ok(#expr) @builtin
|
||||
macro void? @try(#v, #expr) @builtin @maydiscard
|
||||
{
|
||||
var res = #expr;
|
||||
if (catch err = res) return err?;
|
||||
if (catch err = res) return err~;
|
||||
#v = res;
|
||||
}
|
||||
|
||||
@@ -581,7 +581,7 @@ macro bool? @try_catch(#v, #expr, fault expected_fault) @builtin
|
||||
var res = #expr;
|
||||
if (catch err = res)
|
||||
{
|
||||
return err == expected_fault ? true : err?;
|
||||
return err == expected_fault ? true : err~;
|
||||
}
|
||||
#v = res;
|
||||
return false;
|
||||
|
||||
@@ -16,25 +16,25 @@ const uint UTF16_SURROGATE_HIGH_VALUE @private = 0xD800;
|
||||
*>
|
||||
fn usz? char32_to_utf8(Char32 c, char[] output)
|
||||
{
|
||||
if (!output.len) return string::CONVERSION_FAILED?;
|
||||
if (!output.len) return string::CONVERSION_FAILED~;
|
||||
switch (true)
|
||||
{
|
||||
case c <= 0x7f:
|
||||
output[0] = (char)c;
|
||||
return 1;
|
||||
case c <= 0x7ff:
|
||||
if (output.len < 2) return string::CONVERSION_FAILED?;
|
||||
if (output.len < 2) return string::CONVERSION_FAILED~;
|
||||
output[0] = (char)(0xC0 | c >> 6);
|
||||
output[1] = (char)(0x80 | (c & 0x3F));
|
||||
return 2;
|
||||
case c <= 0xffff:
|
||||
if (output.len < 3) return string::CONVERSION_FAILED?;
|
||||
if (output.len < 3) return string::CONVERSION_FAILED~;
|
||||
output[0] = (char)(0xE0 | c >> 12);
|
||||
output[1] = (char)(0x80 | (c >> 6 & 0x3F));
|
||||
output[2] = (char)(0x80 | (c & 0x3F));
|
||||
return 3;
|
||||
case c <= 0x10ffff:
|
||||
if (output.len < 4) return string::CONVERSION_FAILED?;
|
||||
if (output.len < 4) return string::CONVERSION_FAILED~;
|
||||
output[0] = (char)(0xF0 | c >> 18);
|
||||
output[1] = (char)(0x80 | (c >> 12 & 0x3F));
|
||||
output[2] = (char)(0x80 | (c >> 6 & 0x3F));
|
||||
@@ -42,7 +42,7 @@ fn usz? char32_to_utf8(Char32 c, char[] output)
|
||||
return 4;
|
||||
default:
|
||||
// 0x10FFFF and above is not defined.
|
||||
return string::CONVERSION_FAILED?;
|
||||
return string::CONVERSION_FAILED~;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,15 +84,15 @@ fn void? char16_to_utf8_unsafe(Char16 *ptr, usz *available, char** output)
|
||||
return;
|
||||
}
|
||||
// Low surrogate first is an error
|
||||
if (high & UTF16_SURROGATE_MASK != UTF16_SURROGATE_HIGH_VALUE) return string::INVALID_UTF16?;
|
||||
if (high & UTF16_SURROGATE_MASK != UTF16_SURROGATE_HIGH_VALUE) return string::INVALID_UTF16~;
|
||||
|
||||
// Unmatched high surrogate is an error
|
||||
if (*available == 1) return string::INVALID_UTF16?;
|
||||
if (*available == 1) return string::INVALID_UTF16~;
|
||||
|
||||
Char16 low = ptr[1];
|
||||
|
||||
// Unmatched high surrogate, invalid
|
||||
if (low & UTF16_SURROGATE_MASK != UTF16_SURROGATE_LOW_VALUE) return string::INVALID_UTF16?;
|
||||
if (low & UTF16_SURROGATE_MASK != UTF16_SURROGATE_LOW_VALUE) return string::INVALID_UTF16~;
|
||||
|
||||
// The high bits of the codepoint are the value bits of the high surrogate
|
||||
// The low bits of the codepoint are the value bits of the low surrogate
|
||||
@@ -138,7 +138,7 @@ fn usz char32_to_utf8_unsafe(Char32 c, char** output)
|
||||
fn Char32? utf8_to_char32(char* ptr, usz* size)
|
||||
{
|
||||
usz max_size = *size;
|
||||
if (max_size < 1) return string::INVALID_UTF8?;
|
||||
if (max_size < 1) return string::INVALID_UTF8~;
|
||||
char c = (ptr++)[0];
|
||||
|
||||
if ((c & 0x80) == 0)
|
||||
@@ -148,40 +148,40 @@ fn Char32? utf8_to_char32(char* ptr, usz* size)
|
||||
}
|
||||
if ((c & 0xE0) == 0xC0)
|
||||
{
|
||||
if (max_size < 2) return string::INVALID_UTF8?;
|
||||
if (max_size < 2) return string::INVALID_UTF8~;
|
||||
*size = 2;
|
||||
Char32 uc = (c & 0x1F) << 6;
|
||||
c = *ptr;
|
||||
// Overlong sequence or invalid second.
|
||||
if (!uc || c & 0xC0 != 0x80) return string::INVALID_UTF8?;
|
||||
if (!uc || c & 0xC0 != 0x80) return string::INVALID_UTF8~;
|
||||
return uc + c & 0x3F;
|
||||
}
|
||||
if ((c & 0xF0) == 0xE0)
|
||||
{
|
||||
if (max_size < 3) return string::INVALID_UTF8?;
|
||||
if (max_size < 3) return string::INVALID_UTF8~;
|
||||
*size = 3;
|
||||
Char32 uc = (c & 0x0F) << 12;
|
||||
c = ptr++[0];
|
||||
if (c & 0xC0 != 0x80) return string::INVALID_UTF8?;
|
||||
if (c & 0xC0 != 0x80) return string::INVALID_UTF8~;
|
||||
uc += (c & 0x3F) << 6;
|
||||
c = ptr++[0];
|
||||
// Overlong sequence or invalid last
|
||||
if (!uc || c & 0xC0 != 0x80) return string::INVALID_UTF8?;
|
||||
if (!uc || c & 0xC0 != 0x80) return string::INVALID_UTF8~;
|
||||
return uc + c & 0x3F;
|
||||
}
|
||||
if (max_size < 4) return string::INVALID_UTF8?;
|
||||
if ((c & 0xF8) != 0xF0) return string::INVALID_UTF8?;
|
||||
if (max_size < 4) return string::INVALID_UTF8~;
|
||||
if ((c & 0xF8) != 0xF0) return string::INVALID_UTF8~;
|
||||
*size = 4;
|
||||
Char32 uc = (c & 0x07) << 18;
|
||||
c = ptr++[0];
|
||||
if (c & 0xC0 != 0x80) return string::INVALID_UTF8?;
|
||||
if (c & 0xC0 != 0x80) return string::INVALID_UTF8~;
|
||||
uc += (c & 0x3F) << 12;
|
||||
c = ptr++[0];
|
||||
if (c & 0xC0 != 0x80) return string::INVALID_UTF8?;
|
||||
if (c & 0xC0 != 0x80) return string::INVALID_UTF8~;
|
||||
uc += (c & 0x3F) << 6;
|
||||
c = ptr++[0];
|
||||
// Overlong sequence or invalid last
|
||||
if (!uc || c & 0xC0 != 0x80) return string::INVALID_UTF8?;
|
||||
if (!uc || c & 0xC0 != 0x80) return string::INVALID_UTF8~;
|
||||
return uc + c & 0x3F;
|
||||
}
|
||||
|
||||
@@ -329,7 +329,7 @@ fn usz? utf8to32(String utf8, Char32[] utf32_buffer)
|
||||
usz buf_len = utf32_buffer.len;
|
||||
for (usz i = 0; i < len;)
|
||||
{
|
||||
if (len32 == buf_len) return string::CONVERSION_FAILED?;
|
||||
if (len32 == buf_len) return string::CONVERSION_FAILED~;
|
||||
usz width = len - i;
|
||||
Char32 uc = utf8_to_char32(&utf8[i], &width) @inline!;
|
||||
i += width;
|
||||
|
||||
@@ -159,7 +159,7 @@ fn void call_log_internal(LogPriority prio, LogCategory category, String file, S
|
||||
fn String? get_category_name(LogCategory category)
|
||||
{
|
||||
String val = category_names[category];
|
||||
return val ?: NOT_FOUND?;
|
||||
return val ?: NOT_FOUND~;
|
||||
}
|
||||
|
||||
fn void set_category_name(LogCategory category, String name)
|
||||
|
||||
@@ -558,12 +558,12 @@ typedef NullAllocator (Allocator) = uptr;
|
||||
|
||||
fn void*? NullAllocator.acquire(&self, usz bytes, AllocInitType init_type, usz alignment) @dynamic
|
||||
{
|
||||
return mem::OUT_OF_MEMORY?;
|
||||
return mem::OUT_OF_MEMORY~;
|
||||
}
|
||||
|
||||
fn void*? NullAllocator.resize(&self, void* old_ptr, usz new_bytes, usz alignment) @dynamic
|
||||
{
|
||||
return mem::OUT_OF_MEMORY?;
|
||||
return mem::OUT_OF_MEMORY~;
|
||||
}
|
||||
|
||||
fn void NullAllocator.release(&self, void* old_ptr, bool aligned) @dynamic
|
||||
|
||||
@@ -54,11 +54,11 @@ fn void*? alloc(usz size, VirtualMemoryAccess access)
|
||||
if (ptr != posix::MAP_FAILED) return ptr;
|
||||
switch (libc::errno())
|
||||
{
|
||||
case errno::ENOMEM: return mem::OUT_OF_MEMORY?;
|
||||
case errno::EOVERFLOW: return RANGE_OVERFLOW?;
|
||||
case errno::EPERM: return ACCESS_DENIED?;
|
||||
case errno::EINVAL: return INVALID_ARGS?;
|
||||
default: return UNKNOWN_ERROR?;
|
||||
case errno::ENOMEM: return mem::OUT_OF_MEMORY~;
|
||||
case errno::EOVERFLOW: return RANGE_OVERFLOW~;
|
||||
case errno::EPERM: return ACCESS_DENIED~;
|
||||
case errno::EINVAL: return INVALID_ARGS~;
|
||||
default: return UNKNOWN_ERROR~;
|
||||
}
|
||||
$case env::WIN32:
|
||||
void* ptr = win32::virtualAlloc(null, aligned_alloc_size(size), MEM_RESERVE, access.to_win32());
|
||||
@@ -66,8 +66,8 @@ fn void*? alloc(usz size, VirtualMemoryAccess access)
|
||||
switch (win32::getLastError())
|
||||
{
|
||||
case win32::ERROR_NOT_ENOUGH_MEMORY:
|
||||
case win32::ERROR_COMMITMENT_LIMIT: return mem::OUT_OF_MEMORY?;
|
||||
default: return UNKNOWN_ERROR?;
|
||||
case win32::ERROR_COMMITMENT_LIMIT: return mem::OUT_OF_MEMORY~;
|
||||
default: return UNKNOWN_ERROR~;
|
||||
}
|
||||
$default:
|
||||
unsupported("Virtual alloc only available on Win32 and Posix");
|
||||
@@ -89,18 +89,18 @@ fn void? release(void* ptr, usz size)
|
||||
{
|
||||
switch (libc::errno())
|
||||
{
|
||||
case errno::EINVAL: return INVALID_ARGS?; // Not a valid mapping or size
|
||||
case errno::ENOMEM: return UNMAPPED_ACCESS?; // Address not mapped
|
||||
default: return RELEASE_FAILED?;
|
||||
case errno::EINVAL: return INVALID_ARGS~; // Not a valid mapping or size
|
||||
case errno::ENOMEM: return UNMAPPED_ACCESS~; // Address not mapped
|
||||
default: return RELEASE_FAILED~;
|
||||
}
|
||||
}
|
||||
$case env::WIN32:
|
||||
if (win32::virtualFree(ptr, 0, MEM_RELEASE)) return;
|
||||
switch (win32::getLastError())
|
||||
{
|
||||
case win32::ERROR_INVALID_ADDRESS: return INVALID_ARGS?;
|
||||
case win32::ERROR_NOT_ENOUGH_MEMORY: return mem::OUT_OF_MEMORY?;
|
||||
default: return RELEASE_FAILED?;
|
||||
case win32::ERROR_INVALID_ADDRESS: return INVALID_ARGS~;
|
||||
case win32::ERROR_NOT_ENOUGH_MEMORY: return mem::OUT_OF_MEMORY~;
|
||||
default: return RELEASE_FAILED~;
|
||||
}
|
||||
$default:
|
||||
unsupported("Virtual free only available on Win32 and Posix");
|
||||
@@ -124,21 +124,21 @@ fn void? protect(void* ptr, usz len, VirtualMemoryAccess access)
|
||||
if (!posix::mprotect(ptr, len, access.to_posix())) return;
|
||||
switch (libc::errno())
|
||||
{
|
||||
case errno::EACCES: return ACCESS_DENIED?;
|
||||
case errno::EINVAL: return UNALIGNED_ADDRESS?;
|
||||
case errno::EOVERFLOW: return RANGE_OVERFLOW?;
|
||||
case errno::ENOMEM: return UNMAPPED_ACCESS?;
|
||||
default: return UPDATE_FAILED?;
|
||||
case errno::EACCES: return ACCESS_DENIED~;
|
||||
case errno::EINVAL: return UNALIGNED_ADDRESS~;
|
||||
case errno::EOVERFLOW: return RANGE_OVERFLOW~;
|
||||
case errno::ENOMEM: return UNMAPPED_ACCESS~;
|
||||
default: return UPDATE_FAILED~;
|
||||
}
|
||||
$case env::WIN32:
|
||||
Win32_Protect old;
|
||||
if (win32::virtualProtect(ptr, len, access.to_win32(), &old)) return;
|
||||
switch (win32::getLastError())
|
||||
{
|
||||
case win32::ERROR_INVALID_ADDRESS: return UNALIGNED_ADDRESS?;
|
||||
case win32::ERROR_ACCESS_DENIED: return ACCESS_DENIED?;
|
||||
case win32::ERROR_INVALID_PARAMETER: return INVALID_ARGS?;
|
||||
default: return UPDATE_FAILED?;
|
||||
case win32::ERROR_INVALID_ADDRESS: return UNALIGNED_ADDRESS~;
|
||||
case win32::ERROR_ACCESS_DENIED: return ACCESS_DENIED~;
|
||||
case win32::ERROR_INVALID_PARAMETER: return INVALID_ARGS~;
|
||||
default: return UPDATE_FAILED~;
|
||||
}
|
||||
$default:
|
||||
unsupported("'virtual_protect' is only available on Win32 and Posix.");
|
||||
@@ -165,12 +165,12 @@ fn void? commit(void* ptr, usz len, VirtualMemoryAccess access = READWRITE)
|
||||
if (result) return;
|
||||
switch (win32::getLastError())
|
||||
{
|
||||
case win32::ERROR_INVALID_ADDRESS: return UNALIGNED_ADDRESS?;
|
||||
case win32::ERROR_ACCESS_DENIED: return ACCESS_DENIED?;
|
||||
case win32::ERROR_INVALID_ADDRESS: return UNALIGNED_ADDRESS~;
|
||||
case win32::ERROR_ACCESS_DENIED: return ACCESS_DENIED~;
|
||||
case win32::ERROR_COMMITMENT_LIMIT:
|
||||
case win32::ERROR_NOT_ENOUGH_MEMORY: return mem::OUT_OF_MEMORY?;
|
||||
case win32::ERROR_INVALID_PARAMETER: return INVALID_ARGS?;
|
||||
default: return UNKNOWN_ERROR?;
|
||||
case win32::ERROR_NOT_ENOUGH_MEMORY: return mem::OUT_OF_MEMORY~;
|
||||
case win32::ERROR_INVALID_PARAMETER: return INVALID_ARGS~;
|
||||
default: return UNKNOWN_ERROR~;
|
||||
}
|
||||
$default:
|
||||
unsupported("'virtual_commit' is only available on Win32 and Posix.");
|
||||
@@ -197,9 +197,9 @@ fn void? decommit(void* ptr, usz len, bool block = true)
|
||||
{
|
||||
switch (libc::errno())
|
||||
{
|
||||
case errno::EINVAL: return UNALIGNED_ADDRESS?;
|
||||
case errno::ENOMEM: return UNMAPPED_ACCESS?;
|
||||
default: return UPDATE_FAILED?;
|
||||
case errno::EINVAL: return UNALIGNED_ADDRESS~;
|
||||
case errno::ENOMEM: return UNMAPPED_ACCESS~;
|
||||
default: return UPDATE_FAILED~;
|
||||
}
|
||||
}
|
||||
if (block) (void)protect(ptr, len, PROTECTED) @inline;
|
||||
@@ -208,10 +208,10 @@ fn void? decommit(void* ptr, usz len, bool block = true)
|
||||
{
|
||||
switch (win32::getLastError())
|
||||
{
|
||||
case win32::ERROR_INVALID_ADDRESS: return UNALIGNED_ADDRESS?;
|
||||
case win32::ERROR_INVALID_PARAMETER: return INVALID_ARGS?;
|
||||
case win32::ERROR_ACCESS_DENIED: return ACCESS_DENIED?;
|
||||
default: return UPDATE_FAILED?;
|
||||
case win32::ERROR_INVALID_ADDRESS: return UNALIGNED_ADDRESS~;
|
||||
case win32::ERROR_INVALID_PARAMETER: return INVALID_ARGS~;
|
||||
case win32::ERROR_ACCESS_DENIED: return ACCESS_DENIED~;
|
||||
default: return UPDATE_FAILED~;
|
||||
}
|
||||
}
|
||||
$default:
|
||||
@@ -237,15 +237,15 @@ fn void*? mmap_file(Fd fd, usz size, usz offset = 0, VirtualMemoryAccess access
|
||||
if (ptr != posix::MAP_FAILED) return ptr;
|
||||
switch (libc::errno())
|
||||
{
|
||||
case errno::ENOMEM: return mem::OUT_OF_MEMORY?;
|
||||
case errno::EOVERFLOW: return RANGE_OVERFLOW?;
|
||||
case errno::EPERM: return ACCESS_DENIED?;
|
||||
case errno::EINVAL: return INVALID_ARGS?;
|
||||
case errno::EACCES: return io::NO_PERMISSION?;
|
||||
case errno::EBADF: return io::FILE_NOT_VALID?;
|
||||
case errno::EAGAIN: return io::WOULD_BLOCK?;
|
||||
case errno::ENXIO: return io::FILE_NOT_FOUND?;
|
||||
default: return UNKNOWN_ERROR?;
|
||||
case errno::ENOMEM: return mem::OUT_OF_MEMORY~;
|
||||
case errno::EOVERFLOW: return RANGE_OVERFLOW~;
|
||||
case errno::EPERM: return ACCESS_DENIED~;
|
||||
case errno::EINVAL: return INVALID_ARGS~;
|
||||
case errno::EACCES: return io::NO_PERMISSION~;
|
||||
case errno::EBADF: return io::FILE_NOT_VALID~;
|
||||
case errno::EAGAIN: return io::WOULD_BLOCK~;
|
||||
case errno::ENXIO: return io::FILE_NOT_FOUND~;
|
||||
default: return UNKNOWN_ERROR~;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ fn char[]? WasmMemory.allocate_block(&self, usz bytes)
|
||||
}
|
||||
|
||||
usz blocks_required = (bytes_required + WASM_BLOCK_SIZE + 1) / WASM_BLOCK_SIZE;
|
||||
if ($$wasm_memory_grow(0, blocks_required) == -1) return mem::OUT_OF_MEMORY?;
|
||||
if ($$wasm_memory_grow(0, blocks_required) == -1) return mem::OUT_OF_MEMORY~;
|
||||
self.allocation = $$wasm_memory_size(0) * WASM_BLOCK_SIZE;
|
||||
defer self.use += bytes;
|
||||
return ((char*)self.use)[:bytes];
|
||||
|
||||
@@ -79,7 +79,7 @@ fn SegmentCommand64*? find_segment(MachHeader* header, char* segname)
|
||||
}
|
||||
command = (void*)command + command.cmdsize;
|
||||
}
|
||||
return NOT_FOUND?;
|
||||
return NOT_FOUND~;
|
||||
}
|
||||
fn Section64*? find_section(SegmentCommand64* command, char* sectname)
|
||||
{
|
||||
@@ -89,7 +89,7 @@ fn Section64*? find_section(SegmentCommand64* command, char* sectname)
|
||||
if (name_cmp(sectname, §ion.sectname)) return section;
|
||||
section++;
|
||||
}
|
||||
return NOT_FOUND?;
|
||||
return NOT_FOUND~;
|
||||
}
|
||||
|
||||
macro find_segment_section_body(MachHeader* header, char* segname, char* sectname, $Type)
|
||||
|
||||
@@ -27,7 +27,7 @@ macro @enum_lookup($Type, #value, value)
|
||||
$foreach $val : $Type.values:
|
||||
if ($val.#value == value) return $val;
|
||||
$endforeach
|
||||
return NOT_FOUND?;
|
||||
return NOT_FOUND~;
|
||||
}
|
||||
|
||||
macro @enum_lookup_new($Type, $name, value)
|
||||
@@ -35,7 +35,7 @@ macro @enum_lookup_new($Type, $name, value)
|
||||
$foreach $val : $Type.values:
|
||||
if ($val.$eval($name) == value) return $val;
|
||||
$endforeach
|
||||
return NOT_FOUND?;
|
||||
return NOT_FOUND~;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@ fn String bformat(char[] buffer, String fmt, args...) @format(1)
|
||||
OutputFn format_fn = fn void?(void* buf, char c) {
|
||||
char[]* buffer_ref = buf;
|
||||
char[] buffer = *buffer_ref;
|
||||
if (buffer.len == 0) return io::BUFFER_EXCEEDED?;
|
||||
if (buffer.len == 0) return io::BUFFER_EXCEEDED~;
|
||||
buffer[0] = c;
|
||||
*buffer_ref = buffer[1..];
|
||||
};
|
||||
@@ -368,7 +368,7 @@ fn String[] String.split(self, Allocator allocator, String delimiter, usz max =
|
||||
bool no_more = false;
|
||||
while (!no_more)
|
||||
{
|
||||
usz? index = i == max - 1 ? NOT_FOUND? : self.index_of(delimiter);
|
||||
usz? index = i == max - 1 ? NOT_FOUND~ : self.index_of(delimiter);
|
||||
String res @noinit;
|
||||
if (try index)
|
||||
{
|
||||
@@ -427,7 +427,7 @@ fn String[]? String.split_to_buffer(s, String delimiter, String[] buffer, usz ma
|
||||
bool no_more = false;
|
||||
while (!no_more)
|
||||
{
|
||||
usz? index = i == max - 1 ? NOT_FOUND? : s.index_of(delimiter);
|
||||
usz? index = i == max - 1 ? NOT_FOUND~ : s.index_of(delimiter);
|
||||
String res @noinit;
|
||||
if (try index)
|
||||
{
|
||||
@@ -445,7 +445,7 @@ fn String[]? String.split_to_buffer(s, String delimiter, String[] buffer, usz ma
|
||||
}
|
||||
if (i == max_capacity)
|
||||
{
|
||||
return BUFFER_EXCEEDED?;
|
||||
return BUFFER_EXCEEDED~;
|
||||
}
|
||||
buffer[i++] = res;
|
||||
}
|
||||
@@ -526,7 +526,7 @@ fn usz? String.index_of_char(self, char character)
|
||||
{
|
||||
if (c == character) return i;
|
||||
}
|
||||
return NOT_FOUND?;
|
||||
return NOT_FOUND~;
|
||||
}
|
||||
|
||||
<*
|
||||
@@ -549,7 +549,7 @@ fn usz? String.index_of_chars(String self, char[] characters)
|
||||
}
|
||||
}
|
||||
|
||||
return NOT_FOUND?;
|
||||
return NOT_FOUND~;
|
||||
}
|
||||
|
||||
<*
|
||||
@@ -566,12 +566,12 @@ fn usz? String.index_of_chars(String self, char[] characters)
|
||||
fn usz? String.index_of_char_from(self, char character, usz start_index)
|
||||
{
|
||||
usz len = self.len;
|
||||
if (len <= start_index) return NOT_FOUND?;
|
||||
if (len <= start_index) return NOT_FOUND~;
|
||||
for (usz i = start_index; i < len; i++)
|
||||
{
|
||||
if (self[i] == character) return i;
|
||||
}
|
||||
return NOT_FOUND?;
|
||||
return NOT_FOUND~;
|
||||
}
|
||||
|
||||
<*
|
||||
@@ -590,7 +590,7 @@ fn usz? String.rindex_of_char(self, char character)
|
||||
{
|
||||
if (c == character) return i;
|
||||
}
|
||||
return NOT_FOUND?;
|
||||
return NOT_FOUND~;
|
||||
}
|
||||
|
||||
<*
|
||||
@@ -615,7 +615,7 @@ fn usz? String.index_of(self, String substr)
|
||||
if (c == first && self[i : needed] == substr) return i;
|
||||
}
|
||||
}
|
||||
return NOT_FOUND?;
|
||||
return NOT_FOUND~;
|
||||
}
|
||||
|
||||
<*
|
||||
@@ -640,7 +640,7 @@ fn usz? String.rindex_of(self, String substr)
|
||||
if (c == first && self[i : needed] == substr) return i;
|
||||
}
|
||||
}
|
||||
return NOT_FOUND?;
|
||||
return NOT_FOUND~;
|
||||
}
|
||||
|
||||
fn bool ZString.eq(self, ZString other) @operator(==)
|
||||
@@ -1026,12 +1026,12 @@ macro String.to_integer(self, $Type, int base = 10)
|
||||
usz index = 0;
|
||||
char* ptr = self.ptr;
|
||||
while (index < len && ptr[index].is_blank()) index++;
|
||||
if (len == index) return EMPTY_STRING?;
|
||||
if (len == index) return EMPTY_STRING~;
|
||||
bool is_negative;
|
||||
switch (self[index])
|
||||
{
|
||||
case '-':
|
||||
if ($Type.min == 0) return NEGATIVE_VALUE?;
|
||||
if ($Type.min == 0) return NEGATIVE_VALUE~;
|
||||
is_negative = true;
|
||||
index++;
|
||||
case '+':
|
||||
@@ -1039,7 +1039,7 @@ macro String.to_integer(self, $Type, int base = 10)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (len == index) return MALFORMED_INTEGER?;
|
||||
if (len == index) return MALFORMED_INTEGER~;
|
||||
$Type base_used = ($Type)base;
|
||||
if (self[index] == '0' && base == 10)
|
||||
{
|
||||
@@ -1062,7 +1062,7 @@ macro String.to_integer(self, $Type, int base = 10)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (len == index) return MALFORMED_INTEGER?;
|
||||
if (len == index) return MALFORMED_INTEGER~;
|
||||
}
|
||||
$Type value = 0;
|
||||
while (index != len)
|
||||
@@ -1072,18 +1072,18 @@ macro String.to_integer(self, $Type, int base = 10)
|
||||
{
|
||||
case base_used < 10 || c < 'A': c -= '0';
|
||||
case c <= 'F': c -= 'A' - 10;
|
||||
case c < 'a' || c > 'f': return MALFORMED_INTEGER?;
|
||||
case c < 'a' || c > 'f': return MALFORMED_INTEGER~;
|
||||
default: c -= 'a' - 10;
|
||||
}
|
||||
if (c >= base_used) return MALFORMED_INTEGER?;
|
||||
if (c >= base_used) return MALFORMED_INTEGER~;
|
||||
do
|
||||
{
|
||||
if (is_negative)
|
||||
{
|
||||
value = value.overflow_mul(base_used).overflow_sub(c) ?? INTEGER_OVERFLOW?!;
|
||||
value = value.overflow_mul(base_used).overflow_sub(c) ?? INTEGER_OVERFLOW~!;
|
||||
break;
|
||||
}
|
||||
value = value.overflow_mul(base_used).overflow_add(c) ?? INTEGER_OVERFLOW?!;
|
||||
value = value.overflow_mul(base_used).overflow_add(c) ?? INTEGER_OVERFLOW~!;
|
||||
};
|
||||
}
|
||||
return value;
|
||||
@@ -1208,10 +1208,10 @@ fn String? Splitter.next(&self)
|
||||
{
|
||||
usz len = self.string.len;
|
||||
usz current = self.current;
|
||||
if (current > len) return NO_MORE_ELEMENT?;
|
||||
if (current > len) return NO_MORE_ELEMENT~;
|
||||
if (current == len)
|
||||
{
|
||||
if (self.type != TOKENIZE_ALL) return NO_MORE_ELEMENT?;
|
||||
if (self.type != TOKENIZE_ALL) return NO_MORE_ELEMENT~;
|
||||
self.current++;
|
||||
return self.string[current - 1:0];
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ fn String? String.unescape(String s, Allocator allocator, bool allow_unquoted =
|
||||
// Remove quotes.
|
||||
s = s[1:^2];
|
||||
}
|
||||
else if (!allow_unquoted) return UNTERMINATED_STRING?;
|
||||
else if (!allow_unquoted) return UNTERMINATED_STRING~;
|
||||
|
||||
// Handle empty string case
|
||||
if (!s.len)
|
||||
@@ -170,7 +170,7 @@ fn void? unescape_dstring(String s, DString result, bool allow_unquoted = false,
|
||||
}
|
||||
|
||||
// Handle escape sequence
|
||||
if (i + 1 >= len) return INVALID_ESCAPE_SEQUENCE?;
|
||||
if (i + 1 >= len) return INVALID_ESCAPE_SEQUENCE~;
|
||||
|
||||
char escape_char = s[++i];
|
||||
switch (escape_char)
|
||||
@@ -187,38 +187,38 @@ fn void? unescape_dstring(String s, DString result, bool allow_unquoted = false,
|
||||
case '0': result.append_char('\0');
|
||||
case 'x':
|
||||
// Hex escape \xHH
|
||||
if (i + 2 >= len) return INVALID_HEX_ESCAPE?;
|
||||
if (i + 2 >= len) return INVALID_HEX_ESCAPE~;
|
||||
char h1 = s[++i];
|
||||
char h2 = s[++i];
|
||||
if (!h1.is_xdigit() || !h2.is_xdigit()) return INVALID_HEX_ESCAPE?;
|
||||
if (!h1.is_xdigit() || !h2.is_xdigit()) return INVALID_HEX_ESCAPE~;
|
||||
uint val = h1 > '9' ? (h1 | 32) - 'a' + 10 : h1 - '0';
|
||||
val = val << 4;
|
||||
val += h2 > '9' ? (h2 | 32) - 'a' + 10 : h2 - '0';
|
||||
result.append_char((char)val);
|
||||
case 'u':
|
||||
// Unicode escape \uHHHH
|
||||
if (i + 4 >= len) return INVALID_UNICODE_ESCAPE?;
|
||||
if (i + 4 >= len) return INVALID_UNICODE_ESCAPE~;
|
||||
uint val;
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
char hex_char = s[++i];
|
||||
if (!hex_char.is_xdigit()) return INVALID_UNICODE_ESCAPE?;
|
||||
if (!hex_char.is_xdigit()) return INVALID_UNICODE_ESCAPE~;
|
||||
val = val << 4 + (hex_char > '9' ? (hex_char | 32) - 'a' + 10 : hex_char - '0');
|
||||
}
|
||||
result.append_char32(val);
|
||||
case 'U':
|
||||
// Unicode escape \UHHHHHHHH
|
||||
if (i + 8 >= len) return INVALID_UNICODE_ESCAPE?;
|
||||
if (i + 8 >= len) return INVALID_UNICODE_ESCAPE~;
|
||||
uint val;
|
||||
for (int j = 0; j < 8; j++)
|
||||
{
|
||||
char hex_char = s[++i];
|
||||
if (!hex_char.is_xdigit()) return INVALID_UNICODE_ESCAPE?;
|
||||
if (!hex_char.is_xdigit()) return INVALID_UNICODE_ESCAPE~;
|
||||
val = val << 4 + (hex_char > '9' ? (hex_char | 32) - 'a' + 10 : hex_char - '0');
|
||||
}
|
||||
result.append_char32(val);
|
||||
default:
|
||||
if (!lenient) return INVALID_ESCAPE_SEQUENCE?;
|
||||
if (!lenient) return INVALID_ESCAPE_SEQUENCE~;
|
||||
result.append_char(escape_char);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ fn Char32? StringIterator.next(&self)
|
||||
{
|
||||
usz len = self.utf8.len;
|
||||
usz current = self.current;
|
||||
if (current >= len) return NO_MORE_ELEMENT?;
|
||||
if (current >= len) return NO_MORE_ELEMENT~;
|
||||
usz read = (len - current < 4 ? len - current : 4);
|
||||
Char32 res = conv::utf8_to_char32(&self.utf8[current], &read)!;
|
||||
self.current += read;
|
||||
@@ -26,7 +26,7 @@ fn Char32? StringIterator.peek(&self)
|
||||
{
|
||||
usz len = self.utf8.len;
|
||||
usz current = self.current;
|
||||
if (current >= len) return NO_MORE_ELEMENT?;
|
||||
if (current >= len) return NO_MORE_ELEMENT~;
|
||||
usz read = (len - current < 4 ? len - current : 4);
|
||||
Char32 res = conv::utf8_to_char32(&self.utf8[current], &read)!;
|
||||
return res;
|
||||
@@ -43,7 +43,7 @@ fn Char32? StringIterator.get(&self)
|
||||
usz current = self.current;
|
||||
usz read = (len - current < 4 ? len - current : 4);
|
||||
usz index = current > read ? current - read : 0;
|
||||
if (index >= len) return NO_MORE_ELEMENT?;
|
||||
if (index >= len) return NO_MORE_ELEMENT~;
|
||||
Char32 res = conv::utf8_to_char32(&self.utf8[index], &read)!;
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ macro double? decfloat(char[] chars, int $bits, int $emin, int sign)
|
||||
got_rad = true;
|
||||
if (index == last_char)
|
||||
{
|
||||
if (!got_digit) return MALFORMED_FLOAT?;
|
||||
if (!got_digit) return MALFORMED_FLOAT~;
|
||||
return sign * 0.0;
|
||||
}
|
||||
if (index != last_char && (c = chars[++index]) == '0')
|
||||
@@ -83,7 +83,7 @@ macro double? decfloat(char[] chars, int $bits, int $emin, int sign)
|
||||
switch
|
||||
{
|
||||
case c == '.':
|
||||
if (got_rad) return MALFORMED_FLOAT?;
|
||||
if (got_rad) return MALFORMED_FLOAT~;
|
||||
got_rad = true;
|
||||
lrp = dc;
|
||||
case k < KMAX - 3:
|
||||
@@ -113,24 +113,24 @@ macro double? decfloat(char[] chars, int $bits, int $emin, int sign)
|
||||
c = chars[++index];
|
||||
}
|
||||
if (!got_rad) lrp = dc;
|
||||
if (!got_digit) return MALFORMED_FLOAT?;
|
||||
if (!got_digit) return MALFORMED_FLOAT~;
|
||||
if ((c | 32) == 'e')
|
||||
{
|
||||
if (last_char == index) return MALFORMED_FLOAT?;
|
||||
long e10 = String.to_long((String)chars[index + 1..]) ?? MALFORMED_FLOAT?!;
|
||||
if (last_char == index) return MALFORMED_FLOAT~;
|
||||
long e10 = String.to_long((String)chars[index + 1..]) ?? MALFORMED_FLOAT~!;
|
||||
lrp += e10;
|
||||
}
|
||||
else if (index != last_char)
|
||||
{
|
||||
return MALFORMED_FLOAT?;
|
||||
return MALFORMED_FLOAT~;
|
||||
}
|
||||
// Handle zero specially to avoid nasty special cases later
|
||||
if (!x[0]) return sign * 0.0;
|
||||
|
||||
// Optimize small integers (w/no exponent) and over/under-flow
|
||||
if (lrp == dc && dc < 10 && ($bits > 30 || (ulong)x[0] >> $bits == 0)) return sign * (double)x[0];
|
||||
if (lrp > - $emin / 2) return FLOAT_OUT_OF_RANGE?;
|
||||
if (lrp < $emin - 2 * math::DOUBLE_MANT_DIG) return FLOAT_OUT_OF_RANGE?;
|
||||
if (lrp > - $emin / 2) return FLOAT_OUT_OF_RANGE~;
|
||||
if (lrp < $emin - 2 * math::DOUBLE_MANT_DIG) return FLOAT_OUT_OF_RANGE~;
|
||||
|
||||
// Align incomplete final B1B digit
|
||||
if (j)
|
||||
@@ -320,7 +320,7 @@ macro double? decfloat(char[] chars, int $bits, int $emin, int sign)
|
||||
y *= 0.5;
|
||||
e2++;
|
||||
}
|
||||
if (e2 + math::DOUBLE_MANT_DIG > emax || (denormal && frac)) return MALFORMED_FLOAT?;
|
||||
if (e2 + math::DOUBLE_MANT_DIG > emax || (denormal && frac)) return MALFORMED_FLOAT~;
|
||||
}
|
||||
return math::scalbn(y, e2);
|
||||
}
|
||||
@@ -351,7 +351,7 @@ macro double? hexfloat(char[] chars, int $bits, int $emin, int sign)
|
||||
got_rad = true;
|
||||
if (index == last_char)
|
||||
{
|
||||
if (!got_digit) return MALFORMED_FLOAT?;
|
||||
if (!got_digit) return MALFORMED_FLOAT~;
|
||||
return sign * 0.0;
|
||||
}
|
||||
if (index != last_char && (c = chars[++index]) == '0')
|
||||
@@ -369,7 +369,7 @@ macro double? hexfloat(char[] chars, int $bits, int $emin, int sign)
|
||||
{
|
||||
if (c == '.')
|
||||
{
|
||||
if (got_rad) return MALFORMED_FLOAT?;
|
||||
if (got_rad) return MALFORMED_FLOAT~;
|
||||
got_rad = true;
|
||||
rp = dc;
|
||||
}
|
||||
@@ -393,20 +393,20 @@ macro double? hexfloat(char[] chars, int $bits, int $emin, int sign)
|
||||
if (index == last_char) break;
|
||||
c = chars[++index];
|
||||
}
|
||||
if (!got_digit) return MALFORMED_FLOAT?;
|
||||
if (!got_digit) return MALFORMED_FLOAT~;
|
||||
if (!got_rad) rp = dc;
|
||||
for (; dc < 8; dc++) x *= 16;
|
||||
|
||||
long e2;
|
||||
if ((c | 32) == 'p')
|
||||
{
|
||||
long e2val = String.to_long((String)chars[index + 1..]) ?? (MALFORMED_FLOAT?)!;
|
||||
long e2val = String.to_long((String)chars[index + 1..]) ?? MALFORMED_FLOAT~!;
|
||||
e2 = e2val;
|
||||
}
|
||||
e2 += 4 * rp - 32;
|
||||
if (!x) return sign * 0.0;
|
||||
if (e2 > -$emin) return FLOAT_OUT_OF_RANGE?;
|
||||
if (e2 < $emin - 2 * math::DOUBLE_MANT_DIG) return FLOAT_OUT_OF_RANGE?;
|
||||
if (e2 > -$emin) return FLOAT_OUT_OF_RANGE~;
|
||||
if (e2 < $emin - 2 * math::DOUBLE_MANT_DIG) return FLOAT_OUT_OF_RANGE~;
|
||||
|
||||
while (x < 0x80000000)
|
||||
{
|
||||
@@ -441,7 +441,7 @@ macro double? hexfloat(char[] chars, int $bits, int $emin, int sign)
|
||||
}
|
||||
y = bias + sign * (double)x + sign * y;
|
||||
y -= bias;
|
||||
if (!y) return FLOAT_OUT_OF_RANGE?;
|
||||
if (!y) return FLOAT_OUT_OF_RANGE~;
|
||||
|
||||
return math::scalbn(y, (int)e2);
|
||||
}
|
||||
@@ -463,7 +463,7 @@ macro String.to_real(chars, $Type) @private
|
||||
$endswitch
|
||||
|
||||
chars = chars.trim();
|
||||
if (!chars.len) return MALFORMED_FLOAT?;
|
||||
if (!chars.len) return MALFORMED_FLOAT~;
|
||||
|
||||
if (chars.len != 1)
|
||||
{
|
||||
@@ -477,7 +477,7 @@ macro String.to_real(chars, $Type) @private
|
||||
}
|
||||
}
|
||||
chars = chars.trim();
|
||||
if (!chars.len) return MALFORMED_FLOAT?;
|
||||
if (!chars.len) return MALFORMED_FLOAT~;
|
||||
|
||||
if (chars == "infinity" || chars == "INFINITY") return sign * $Type.inf;
|
||||
if (chars == "NAN" || chars == "nan") return $Type.nan;
|
||||
|
||||
@@ -12,7 +12,7 @@ faultdef DIVISION_BY_ZERO;
|
||||
|
||||
fn double? divide(int a, int b)
|
||||
{
|
||||
if (b == 0) return MathError.DIVISION_BY_ZERO?;
|
||||
if (b == 0) return MathError.DIVISION_BY_ZERO~;
|
||||
return (double)(a) / (double)(b);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,47 +29,47 @@ macro any_to_int(any v, $Type)
|
||||
{
|
||||
case ichar:
|
||||
ichar c = *(char*)v.ptr;
|
||||
if (is_mixed_signed && c < 0) return VALUE_OUT_OF_UNSIGNED_RANGE?;
|
||||
if (is_mixed_signed && c < 0) return VALUE_OUT_OF_UNSIGNED_RANGE~;
|
||||
return ($Type)c;
|
||||
case short:
|
||||
short s = *(short*)v.ptr;
|
||||
if (is_mixed_signed && s < 0) return VALUE_OUT_OF_UNSIGNED_RANGE?;
|
||||
if (s > max || s < min) return VALUE_OUT_OF_RANGE?;
|
||||
if (is_mixed_signed && s < 0) return VALUE_OUT_OF_UNSIGNED_RANGE~;
|
||||
if (s > max || s < min) return VALUE_OUT_OF_RANGE~;
|
||||
return ($Type)s;
|
||||
case int:
|
||||
int i = *(int*)v.ptr;
|
||||
if (is_mixed_signed && i < 0) return VALUE_OUT_OF_UNSIGNED_RANGE?;
|
||||
if (i > max || i < min) return VALUE_OUT_OF_RANGE?;
|
||||
if (is_mixed_signed && i < 0) return VALUE_OUT_OF_UNSIGNED_RANGE~;
|
||||
if (i > max || i < min) return VALUE_OUT_OF_RANGE~;
|
||||
return ($Type)i;
|
||||
case long:
|
||||
long l = *(long*)v.ptr;
|
||||
if (is_mixed_signed && l < 0) return VALUE_OUT_OF_UNSIGNED_RANGE?;
|
||||
if (l > max || l < min) return VALUE_OUT_OF_RANGE?;
|
||||
if (is_mixed_signed && l < 0) return VALUE_OUT_OF_UNSIGNED_RANGE~;
|
||||
if (l > max || l < min) return VALUE_OUT_OF_RANGE~;
|
||||
return ($Type)l;
|
||||
case int128:
|
||||
int128 i = *(int128*)v.ptr;
|
||||
if (is_mixed_signed && i < 0) return VALUE_OUT_OF_UNSIGNED_RANGE?;
|
||||
if (i > max || i < min) return VALUE_OUT_OF_RANGE?;
|
||||
if (is_mixed_signed && i < 0) return VALUE_OUT_OF_UNSIGNED_RANGE~;
|
||||
if (i > max || i < min) return VALUE_OUT_OF_RANGE~;
|
||||
return ($Type)i;
|
||||
case char:
|
||||
char c = *(char*)v.ptr;
|
||||
if (c > max) return VALUE_OUT_OF_RANGE?;
|
||||
if (c > max) return VALUE_OUT_OF_RANGE~;
|
||||
return ($Type)c;
|
||||
case ushort:
|
||||
ushort s = *(ushort*)v.ptr;
|
||||
if (s > max || s < min) return VALUE_OUT_OF_RANGE?;
|
||||
if (s > max || s < min) return VALUE_OUT_OF_RANGE~;
|
||||
return ($Type)s;
|
||||
case uint:
|
||||
uint i = *(uint*)v.ptr;
|
||||
if (i > max || i < min) return VALUE_OUT_OF_RANGE?;
|
||||
if (i > max || i < min) return VALUE_OUT_OF_RANGE~;
|
||||
return ($Type)i;
|
||||
case ulong:
|
||||
ulong l = *(ulong*)v.ptr;
|
||||
if (l > max || l < min) return VALUE_OUT_OF_RANGE?;
|
||||
if (l > max || l < min) return VALUE_OUT_OF_RANGE~;
|
||||
return ($Type)l;
|
||||
case uint128:
|
||||
uint128 i = *(uint128*)v.ptr;
|
||||
if (i > max || i < min) return VALUE_OUT_OF_RANGE?;
|
||||
if (i > max || i < min) return VALUE_OUT_OF_RANGE~;
|
||||
return ($Type)i;
|
||||
default:
|
||||
unreachable();
|
||||
|
||||
@@ -101,12 +101,12 @@ fn char[]? decode_buffer(char[] src, char[] dst, char padding = DEFAULT_PAD, Bas
|
||||
{
|
||||
if (src.len == 0)
|
||||
{
|
||||
if (padding > 0) return encoding::INVALID_PADDING?;
|
||||
if (padding > 0) return encoding::INVALID_PADDING~;
|
||||
break;
|
||||
}
|
||||
if (src[0] == padding) break;
|
||||
buf[i] = alphabet.reverse[src[0]];
|
||||
if (buf[i] == INVALID) return encoding::INVALID_CHARACTER?;
|
||||
if (buf[i] == INVALID) return encoding::INVALID_CHARACTER~;
|
||||
src = src[1..];
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ fn char[]? decode_buffer(char[] src, char[] dst, char padding = DEFAULT_PAD, Bas
|
||||
dst[0] = buf[1] >> 2 | buf[0] << 3;
|
||||
n++;
|
||||
default:
|
||||
return encoding::INVALID_CHARACTER?;
|
||||
return encoding::INVALID_CHARACTER~;
|
||||
}
|
||||
if (dst.len < 5) break;
|
||||
dst = dst[5..];
|
||||
|
||||
@@ -87,11 +87,11 @@ fn usz? decode_len(usz n, char padding)
|
||||
usz trailing = n % 4;
|
||||
if (padding)
|
||||
{
|
||||
if (trailing != 0) return encoding::INVALID_PADDING?;
|
||||
if (trailing != 0) return encoding::INVALID_PADDING~;
|
||||
// source size is multiple of 4
|
||||
return dn;
|
||||
}
|
||||
if (trailing == 1) return encoding::INVALID_PADDING?;
|
||||
if (trailing == 1) return encoding::INVALID_PADDING~;
|
||||
return dn + trailing * 3 / 4;
|
||||
}
|
||||
|
||||
@@ -196,7 +196,7 @@ fn char[]? decode_buffer(char[] src, char[] dst, char padding = DEFAULT_PAD, Bas
|
||||
case c1:
|
||||
case c2:
|
||||
case c3:
|
||||
return encoding::INVALID_CHARACTER?;
|
||||
return encoding::INVALID_CHARACTER~;
|
||||
}
|
||||
uint group = (uint)c0 << 18 | (uint)c1 << 12 | (uint)c2 << 6 | (uint)c3;
|
||||
dst[0] = (char)(group >> 16);
|
||||
@@ -211,7 +211,7 @@ fn char[]? decode_buffer(char[] src, char[] dst, char padding = DEFAULT_PAD, Bas
|
||||
src = src[^trailing..];
|
||||
char c0 = alphabet.reverse[src[0]];
|
||||
char c1 = alphabet.reverse[src[1]];
|
||||
if (c0 == 0xFF || c1 == 0xFF) return encoding::INVALID_PADDING?;
|
||||
if (c0 == 0xFF || c1 == 0xFF) return encoding::INVALID_PADDING~;
|
||||
if (!padding)
|
||||
{
|
||||
switch (src.len)
|
||||
@@ -221,7 +221,7 @@ fn char[]? decode_buffer(char[] src, char[] dst, char padding = DEFAULT_PAD, Bas
|
||||
dst[0] = (char)(group >> 16);
|
||||
case 3:
|
||||
char c2 = alphabet.reverse[src[2]];
|
||||
if (c2 == 0xFF) return encoding::INVALID_CHARACTER?;
|
||||
if (c2 == 0xFF) return encoding::INVALID_CHARACTER~;
|
||||
uint group = (uint)c0 << 18 | (uint)c1 << 12 | (uint)c2 << 6;
|
||||
dst[0] = (char)(group >> 16);
|
||||
dst[1] = (char)(group >> 8);
|
||||
@@ -235,13 +235,13 @@ fn char[]? decode_buffer(char[] src, char[] dst, char padding = DEFAULT_PAD, Bas
|
||||
switch (padding)
|
||||
{
|
||||
case src[2]:
|
||||
if (src[3] != padding) return encoding::INVALID_PADDING?;
|
||||
if (src[3] != padding) return encoding::INVALID_PADDING~;
|
||||
uint group = (uint)c0 << 18 | (uint)c1 << 12;
|
||||
dst[0] = (char)(group >> 16);
|
||||
dn -= 2;
|
||||
case src[3]:
|
||||
char c2 = alphabet.reverse[src[2]];
|
||||
if (c2 == 0xFF) return encoding::INVALID_CHARACTER?;
|
||||
if (c2 == 0xFF) return encoding::INVALID_CHARACTER~;
|
||||
uint group = (uint)c0 << 18 | (uint)c1 << 12 | (uint)c2 << 6;
|
||||
dst[0] = (char)(group >> 16);
|
||||
dst[1] = (char)(group >> 8);
|
||||
|
||||
@@ -79,7 +79,7 @@ macro void? @each_row(InStream stream, String separator = ",", int max_rows = in
|
||||
if (catch err = s)
|
||||
{
|
||||
if (err == io::EOF) return;
|
||||
return err?;
|
||||
return err~;
|
||||
}
|
||||
@body(s.split(mem, separator));
|
||||
};
|
||||
|
||||
@@ -81,7 +81,7 @@ fn usz? decode_bytes(char[] src, char[] dst)
|
||||
{
|
||||
char a = HEXREVERSE[src[j - 1]];
|
||||
char b = HEXREVERSE[src[j]];
|
||||
if (a > 0x0f || b > 0x0f) return encoding::INVALID_CHARACTER?;
|
||||
if (a > 0x0f || b > 0x0f) return encoding::INVALID_CHARACTER~;
|
||||
dst[i] = (a << 4) | b;
|
||||
i++;
|
||||
}
|
||||
|
||||
@@ -85,13 +85,13 @@ fn Object*? parse_from_token(JsonContext* context, JsonTokenType token) @local
|
||||
case COMMA:
|
||||
case RBRACE:
|
||||
case RBRACKET:
|
||||
case COLON: return UNEXPECTED_CHARACTER?;
|
||||
case COLON: return UNEXPECTED_CHARACTER~;
|
||||
case STRING: return object::new_string(context.last_string.str_view(), context.allocator);
|
||||
case NUMBER: return object::new_float(context.last_number, context.allocator);
|
||||
case TRUE: return object::new_bool(true);
|
||||
case FALSE: return object::new_bool(false);
|
||||
case NULL: return object::new_null();
|
||||
case EOF: return io::EOF?;
|
||||
case EOF: return io::EOF~;
|
||||
}
|
||||
}
|
||||
fn Object*? parse_any(JsonContext* context) @local
|
||||
@@ -117,7 +117,7 @@ fn JsonTokenType? lex_number(JsonContext *context, char c) @local
|
||||
c = read_next(context)!;
|
||||
if (leading_zero)
|
||||
{
|
||||
if (c.is_digit()) return INVALID_NUMBER?;
|
||||
if (c.is_digit()) return INVALID_NUMBER~;
|
||||
leading_zero = false;
|
||||
}
|
||||
}
|
||||
@@ -140,7 +140,7 @@ fn JsonTokenType? lex_number(JsonContext *context, char c) @local
|
||||
t.append(c);
|
||||
c = read_next(context)!;
|
||||
}
|
||||
if (!c.is_digit()) return INVALID_NUMBER?;
|
||||
if (!c.is_digit()) return INVALID_NUMBER~;
|
||||
while (c.is_digit())
|
||||
{
|
||||
t.append(c);
|
||||
@@ -148,7 +148,7 @@ fn JsonTokenType? lex_number(JsonContext *context, char c) @local
|
||||
}
|
||||
}
|
||||
pushback(context, c);
|
||||
double? d = t.str_view().to_double() ?? INVALID_NUMBER?;
|
||||
double? d = t.str_view().to_double() ?? INVALID_NUMBER~;
|
||||
context.last_number = d!;
|
||||
return NUMBER;
|
||||
};
|
||||
@@ -160,14 +160,14 @@ fn Object*? parse_map(JsonContext* context) @local
|
||||
defer catch map.free();
|
||||
JsonTokenType token = advance(context)!;
|
||||
defer context.depth--;
|
||||
if (++context.depth >= max_depth) return json::MAX_DEPTH_REACHED?;
|
||||
if (++context.depth >= max_depth) return json::MAX_DEPTH_REACHED~;
|
||||
|
||||
@stack_mem(256; Allocator mem)
|
||||
{
|
||||
DString temp_key = dstring::new_with_capacity(mem, 32);
|
||||
while (token != JsonTokenType.RBRACE)
|
||||
{
|
||||
if (token != JsonTokenType.STRING) return UNEXPECTED_CHARACTER?;
|
||||
if (token != JsonTokenType.STRING) return UNEXPECTED_CHARACTER~;
|
||||
DString string = context.last_string;
|
||||
// Copy the key to our temp holder, since our
|
||||
// last_string may be used in parse_any
|
||||
@@ -182,7 +182,7 @@ fn Object*? parse_map(JsonContext* context) @local
|
||||
token = advance(context)!;
|
||||
continue;
|
||||
}
|
||||
if (token != JsonTokenType.RBRACE) return UNEXPECTED_CHARACTER?;
|
||||
if (token != JsonTokenType.RBRACE) return UNEXPECTED_CHARACTER~;
|
||||
}
|
||||
return map;
|
||||
};
|
||||
@@ -193,7 +193,7 @@ fn Object*? parse_array(JsonContext* context) @local
|
||||
Object* list = object::new_obj(context.allocator);
|
||||
defer catch list.free();
|
||||
defer context.depth--;
|
||||
if (++context.depth >= max_depth) return json::MAX_DEPTH_REACHED?;
|
||||
if (++context.depth >= max_depth) return json::MAX_DEPTH_REACHED~;
|
||||
JsonTokenType token = advance(context)!;
|
||||
while (token != JsonTokenType.RBRACKET)
|
||||
{
|
||||
@@ -205,7 +205,7 @@ fn Object*? parse_array(JsonContext* context) @local
|
||||
token = advance(context)!;
|
||||
continue;
|
||||
}
|
||||
if (token != JsonTokenType.RBRACKET) return UNEXPECTED_CHARACTER?;
|
||||
if (token != JsonTokenType.RBRACKET) return UNEXPECTED_CHARACTER~;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
@@ -236,7 +236,7 @@ fn char? read_next(JsonContext* context) @local
|
||||
context.reached_end = true;
|
||||
return '\0';
|
||||
}
|
||||
return err?;
|
||||
return err~;
|
||||
}
|
||||
if (c == 0)
|
||||
{
|
||||
@@ -293,7 +293,7 @@ fn JsonTokenType? advance(JsonContext* context) @local
|
||||
switch (c)
|
||||
{
|
||||
case '\0':
|
||||
return io::EOF?;
|
||||
return io::EOF~;
|
||||
case '{':
|
||||
return LBRACE;
|
||||
case '}':
|
||||
@@ -321,7 +321,7 @@ fn JsonTokenType? advance(JsonContext* context) @local
|
||||
match(context, "ull")!;
|
||||
return NULL;
|
||||
default:
|
||||
return UNEXPECTED_CHARACTER?;
|
||||
return UNEXPECTED_CHARACTER~;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -330,13 +330,13 @@ fn void? match(JsonContext* context, String str) @local
|
||||
foreach (c : str)
|
||||
{
|
||||
char l = read_next(context)!;
|
||||
if (l != c) return UNEXPECTED_CHARACTER?;
|
||||
if (l != c) return UNEXPECTED_CHARACTER~;
|
||||
}
|
||||
}
|
||||
|
||||
fn void? parse_expected(JsonContext* context, JsonTokenType token) @local
|
||||
{
|
||||
if (advance(context)! != token) return UNEXPECTED_CHARACTER?;
|
||||
if (advance(context)! != token) return UNEXPECTED_CHARACTER~;
|
||||
}
|
||||
|
||||
fn JsonTokenType? lex_string(JsonContext* context)
|
||||
@@ -348,9 +348,9 @@ fn JsonTokenType? lex_string(JsonContext* context)
|
||||
switch (c)
|
||||
{
|
||||
case '\0':
|
||||
return io::EOF?;
|
||||
return io::EOF~;
|
||||
case 1..31:
|
||||
return UNEXPECTED_CHARACTER?;
|
||||
return UNEXPECTED_CHARACTER~;
|
||||
case '"':
|
||||
break LOOP;
|
||||
case '\\':
|
||||
@@ -363,9 +363,9 @@ fn JsonTokenType? lex_string(JsonContext* context)
|
||||
switch (c)
|
||||
{
|
||||
case '\0':
|
||||
return io::EOF?;
|
||||
return io::EOF~;
|
||||
case 1..31:
|
||||
return UNEXPECTED_CHARACTER?;
|
||||
return UNEXPECTED_CHARACTER~;
|
||||
case '"':
|
||||
case '\\':
|
||||
case '/':
|
||||
@@ -385,13 +385,13 @@ fn JsonTokenType? lex_string(JsonContext* context)
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
c = read_next(context)!;
|
||||
if (!c.is_xdigit()) return INVALID_ESCAPE_SEQUENCE?;
|
||||
if (!c.is_xdigit()) return INVALID_ESCAPE_SEQUENCE~;
|
||||
val = val << 4 + (c > '9' ? (c | 32) - 'a' + 10 : c - '0');
|
||||
}
|
||||
context.last_string.append_char32(val);
|
||||
continue;
|
||||
default:
|
||||
return INVALID_ESCAPE_SEQUENCE?;
|
||||
return INVALID_ESCAPE_SEQUENCE~;
|
||||
}
|
||||
context.last_string.append(c);
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ fn Event? FrameScheduler.pop_event(&self)
|
||||
while (true)
|
||||
{
|
||||
if (try event = self.events.pop()) return event;
|
||||
if (!@atomic_load(self.pending)) return NO_MORE_ELEMENT?;
|
||||
if (!@atomic_load(self.pending)) return NO_MORE_ELEMENT~;
|
||||
self.mtx.@in_lock()
|
||||
{
|
||||
self.events.add_all(&self.pending_events);
|
||||
@@ -88,7 +88,7 @@ fn Event? FrameScheduler.pop_event(&self)
|
||||
self.events.push(self.delayed_events.pop()!!);
|
||||
}
|
||||
@atomic_store(self.pending, self.delayed_events.len() > 0);
|
||||
if (!self.events.len()) return NO_MORE_ELEMENT?;
|
||||
if (!self.events.len()) return NO_MORE_ELEMENT~;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,8 +102,8 @@ fn void? File.close(&self) @inline @dynamic
|
||||
switch (libc::errno())
|
||||
{
|
||||
case errno::ECONNRESET:
|
||||
case errno::EBADF: return io::FILE_NOT_VALID?;
|
||||
case errno::EINTR: return io::INTERRUPTED?;
|
||||
case errno::EBADF: return io::FILE_NOT_VALID~;
|
||||
case errno::EINTR: return io::INTERRUPTED~;
|
||||
case errno::EDQUOT:
|
||||
case errno::EFAULT:
|
||||
case errno::EAGAIN:
|
||||
@@ -111,8 +111,8 @@ fn void? File.close(&self) @inline @dynamic
|
||||
case errno::ENETDOWN:
|
||||
case errno::ENETUNREACH:
|
||||
case errno::ENOSPC:
|
||||
case errno::EIO: return io::INCOMPLETE_WRITE?;
|
||||
default: return io::UNKNOWN_ERROR?;
|
||||
case errno::EIO: return io::INCOMPLETE_WRITE~;
|
||||
default: return io::UNKNOWN_ERROR~;
|
||||
}
|
||||
}
|
||||
self.file = null;
|
||||
@@ -156,7 +156,7 @@ fn bool File.isatty(self) @if(env::LIBC)
|
||||
fn char? File.read_byte(&self) @dynamic
|
||||
{
|
||||
int c = libc::fgetc(self.file);
|
||||
if (c == -1) return io::EOF?;
|
||||
if (c == -1) return io::EOF~;
|
||||
return (char)c;
|
||||
}
|
||||
|
||||
@@ -172,7 +172,7 @@ 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 io::OVERFLOW?;
|
||||
if (len > buffer.len) return io::OVERFLOW~;
|
||||
file.seek(0, SET)!;
|
||||
usz read = 0;
|
||||
while (read < len)
|
||||
|
||||
@@ -26,8 +26,8 @@ fn void? FileMmap.destroy(&self) @maydiscard
|
||||
{
|
||||
fault err1 = @catch(self.file.close());
|
||||
fault err2 = @catch(self.vm.destroy());
|
||||
if (err1) return err1?;
|
||||
if (err2) return err2?;
|
||||
if (err1) return err1~;
|
||||
if (err2) return err2~;
|
||||
}
|
||||
|
||||
module std::io::file @if(env::LIBC &&& env::POSIX);
|
||||
|
||||
@@ -96,9 +96,9 @@ fn usz? Formatter.out(&self, char c) @private
|
||||
{
|
||||
if (catch err = self.out_fn(self.data, c))
|
||||
{
|
||||
if (self.first_fault) return self.first_fault?;
|
||||
if (self.first_fault) return self.first_fault~;
|
||||
self.first_fault = err;
|
||||
return err?;
|
||||
return err~;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -133,7 +133,7 @@ fn usz? Formatter.print_with_function(&self, Printable arg)
|
||||
if (!arg) return self.out_substr("(null)");
|
||||
return self.out_substr(arg.to_constant_string());
|
||||
}
|
||||
return NOT_FOUND?;
|
||||
return NOT_FOUND~;
|
||||
}
|
||||
|
||||
fn usz? Formatter.out_unknown(&self, String category, any arg) @private
|
||||
@@ -340,7 +340,7 @@ fn void? out_null_fn(void* data @unused, char c @unused) @private
|
||||
macro usz? @report_fault(Formatter* f, $fault)
|
||||
{
|
||||
(void)f.out_substr($fault);
|
||||
return INVALID_FORMAT?;
|
||||
return INVALID_FORMAT~;
|
||||
}
|
||||
|
||||
macro usz? @wrap_bad(Formatter* f, #action)
|
||||
@@ -352,11 +352,11 @@ macro usz? @wrap_bad(Formatter* f, #action)
|
||||
{
|
||||
case BUFFER_EXCEEDED:
|
||||
case INTERNAL_BUFFER_EXCEEDED:
|
||||
return f.first_err(err)?;
|
||||
return f.first_err(err)~;
|
||||
default:
|
||||
err = f.first_err(INVALID_ARGUMENT);
|
||||
f.out_substr("<INVALID>")!;
|
||||
return err?;
|
||||
return err~;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
@@ -564,7 +564,7 @@ fn usz? Formatter.vprintf(&self, String format, any[] anys)
|
||||
// out((char)0, buffer, idx < maxlen ? idx : maxlen - 1U, maxlen);
|
||||
|
||||
// return written chars without terminating \0
|
||||
if (self.first_fault) return self.first_fault?;
|
||||
if (self.first_fault) return self.first_fault~;
|
||||
return total_len;
|
||||
}
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ fn uint128? int_from_any(any arg, bool *is_neg) @private
|
||||
double d = *(double*)arg;
|
||||
return (uint128)((*is_neg = d < 0) ? -d : d);
|
||||
default:
|
||||
return BAD_FORMAT?;
|
||||
return BAD_FORMAT~;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ fn FloatType? float_from_any(any arg) @private
|
||||
case double:
|
||||
return (FloatType)*(double*)arg;
|
||||
default:
|
||||
return BAD_FORMAT?;
|
||||
return BAD_FORMAT~;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,7 +283,7 @@ fn usz? Formatter.floatformat(&self, FloatFormatting formatting, double y) @priv
|
||||
} while (y);
|
||||
isz outlen = s - buf;
|
||||
isz explen = ebuf - estr;
|
||||
if (p > int.max - 2 - explen - pl) return INTERNAL_BUFFER_EXCEEDED?;
|
||||
if (p > int.max - 2 - explen - pl) return INTERNAL_BUFFER_EXCEEDED~;
|
||||
usz len;
|
||||
usz l = p && outlen - 2 < p
|
||||
? p + 2 + explen
|
||||
@@ -454,12 +454,12 @@ fn usz? Formatter.floatformat(&self, FloatFormatting formatting, double y) @priv
|
||||
}
|
||||
}
|
||||
}
|
||||
if (p > int.max - 1 - (isz)(p || self.flags.hash)) return INTERNAL_BUFFER_EXCEEDED?;
|
||||
if (p > int.max - 1 - (isz)(p || self.flags.hash)) return INTERNAL_BUFFER_EXCEEDED~;
|
||||
int l = (int)(1 + p + (isz)(p || self.flags.hash));
|
||||
char* estr @noinit;
|
||||
if (formatting == FLOAT)
|
||||
{
|
||||
if (e > int.max - l) return INTERNAL_BUFFER_EXCEEDED?;
|
||||
if (e > int.max - l) return INTERNAL_BUFFER_EXCEEDED~;
|
||||
if (e > 0) l += e;
|
||||
}
|
||||
else
|
||||
@@ -468,10 +468,10 @@ fn usz? Formatter.floatformat(&self, FloatFormatting formatting, double y) @priv
|
||||
while (ebuf - estr < 2) (--estr)[0] = '0';
|
||||
*--estr = (e < 0 ? '-' : '+');
|
||||
*--estr = self.flags.uppercase ? 'E' : 'e';
|
||||
if (ebuf - estr > (isz)int.max - l) return INTERNAL_BUFFER_EXCEEDED?;
|
||||
if (ebuf - estr > (isz)int.max - l) return INTERNAL_BUFFER_EXCEEDED~;
|
||||
l += (int)(ebuf - estr);
|
||||
}
|
||||
if (l > int.max - pl) return INTERNAL_BUFFER_EXCEEDED?;
|
||||
if (l > int.max - pl) return INTERNAL_BUFFER_EXCEEDED~;
|
||||
usz len;
|
||||
if (!self.flags.left && !self.flags.zeropad) len += self.pad(' ', self.width, pl + l)!;
|
||||
if (is_neg || self.flags.plus) len += self.out(is_neg ? '-' : '+')!;
|
||||
@@ -559,7 +559,7 @@ fn usz? Formatter.ntoa(&self, uint128 value, bool negative, uint base) @private
|
||||
case 2:
|
||||
do
|
||||
{
|
||||
if (len >= PRINTF_NTOA_BUFFER_SIZE) return INTERNAL_BUFFER_EXCEEDED?;
|
||||
if (len >= PRINTF_NTOA_BUFFER_SIZE) return INTERNAL_BUFFER_EXCEEDED~;
|
||||
buf[len++] = '0' + (char)value & 1;
|
||||
value >>= 1;
|
||||
}
|
||||
@@ -567,13 +567,13 @@ fn usz? Formatter.ntoa(&self, uint128 value, bool negative, uint base) @private
|
||||
case 10:
|
||||
if (!value)
|
||||
{
|
||||
if (len >= PRINTF_NTOA_BUFFER_SIZE) return INTERNAL_BUFFER_EXCEEDED?;
|
||||
if (len >= PRINTF_NTOA_BUFFER_SIZE) return INTERNAL_BUFFER_EXCEEDED~;
|
||||
buf[len++] = '0';
|
||||
break;
|
||||
}
|
||||
while (value >= 10)
|
||||
{
|
||||
if (len + 1 >= PRINTF_NTOA_BUFFER_SIZE) return INTERNAL_BUFFER_EXCEEDED?;
|
||||
if (len + 1 >= PRINTF_NTOA_BUFFER_SIZE) return INTERNAL_BUFFER_EXCEEDED~;
|
||||
char digit = (char)(value % 100);
|
||||
buf[len:2] = DIGIT_PAIRS[2 * digit:2];
|
||||
len += 2;
|
||||
@@ -581,13 +581,13 @@ fn usz? Formatter.ntoa(&self, uint128 value, bool negative, uint base) @private
|
||||
}
|
||||
if (value > 0)
|
||||
{
|
||||
if (len >= PRINTF_NTOA_BUFFER_SIZE) return INTERNAL_BUFFER_EXCEEDED?;
|
||||
if (len >= PRINTF_NTOA_BUFFER_SIZE) return INTERNAL_BUFFER_EXCEEDED~;
|
||||
buf[len++] = '0' + (char)value;
|
||||
}
|
||||
case 16:
|
||||
do
|
||||
{
|
||||
if (len >= PRINTF_NTOA_BUFFER_SIZE) return INTERNAL_BUFFER_EXCEEDED?;
|
||||
if (len >= PRINTF_NTOA_BUFFER_SIZE) return INTERNAL_BUFFER_EXCEEDED~;
|
||||
char digit = (char)value & 0xF;
|
||||
buf[len++] = digit + (digit < 10 ? '0' : past_10);
|
||||
value >>= 4;
|
||||
@@ -596,7 +596,7 @@ fn usz? Formatter.ntoa(&self, uint128 value, bool negative, uint base) @private
|
||||
case 8:
|
||||
do
|
||||
{
|
||||
if (len >= PRINTF_NTOA_BUFFER_SIZE) return INTERNAL_BUFFER_EXCEEDED?;
|
||||
if (len >= PRINTF_NTOA_BUFFER_SIZE) return INTERNAL_BUFFER_EXCEEDED~;
|
||||
buf[len++] = '0' + (char)value & 0x7;
|
||||
value >>= 3;
|
||||
}
|
||||
@@ -616,12 +616,12 @@ fn usz? Formatter.ntoa_format(&self, String buf, usz len, bool negative, uint ba
|
||||
if (self.width && self.flags.zeropad && (negative || self.flags.plus || self.flags.space)) self.width--;
|
||||
while (len < self.prec)
|
||||
{
|
||||
if (len >= buf.len) return INTERNAL_BUFFER_EXCEEDED?;
|
||||
if (len >= buf.len) return INTERNAL_BUFFER_EXCEEDED~;
|
||||
buf[len++] = '0';
|
||||
}
|
||||
while (self.flags.zeropad && len < self.width)
|
||||
{
|
||||
if (len >= buf.len) return INTERNAL_BUFFER_EXCEEDED?;
|
||||
if (len >= buf.len) return INTERNAL_BUFFER_EXCEEDED~;
|
||||
buf[len++] = '0';
|
||||
}
|
||||
}
|
||||
@@ -636,7 +636,7 @@ fn usz? Formatter.ntoa_format(&self, String buf, usz len, bool negative, uint ba
|
||||
}
|
||||
if (base != 10)
|
||||
{
|
||||
if (len + 1 >= buf.len) return INTERNAL_BUFFER_EXCEEDED?;
|
||||
if (len + 1 >= buf.len) return INTERNAL_BUFFER_EXCEEDED~;
|
||||
switch (base)
|
||||
{
|
||||
case 16:
|
||||
@@ -655,13 +655,13 @@ fn usz? Formatter.ntoa_format(&self, String buf, usz len, bool negative, uint ba
|
||||
switch (true)
|
||||
{
|
||||
case negative:
|
||||
if (len >= buf.len) return INTERNAL_BUFFER_EXCEEDED?;
|
||||
if (len >= buf.len) return INTERNAL_BUFFER_EXCEEDED~;
|
||||
buf[len++] = '-';
|
||||
case self.flags.plus:
|
||||
if (len >= buf.len) return INTERNAL_BUFFER_EXCEEDED?;
|
||||
if (len >= buf.len) return INTERNAL_BUFFER_EXCEEDED~;
|
||||
buf[len++] = '+';
|
||||
case self.flags.space:
|
||||
if (len >= buf.len) return INTERNAL_BUFFER_EXCEEDED?;
|
||||
if (len >= buf.len) return INTERNAL_BUFFER_EXCEEDED~;
|
||||
buf[len++] = ' ';
|
||||
}
|
||||
if (len) self.out_reverse(buf[:len])!;
|
||||
@@ -741,10 +741,10 @@ fn int? printf_parse_format_field(
|
||||
if (c.is_digit()) return simple_atoi(format_ptr, format_len, index_ptr);
|
||||
if (c != '*') return 0;
|
||||
usz len = ++(*index_ptr);
|
||||
if (len >= format_len) return BAD_FORMAT?;
|
||||
if (*args_index_ptr >= args_len) return BAD_FORMAT?;
|
||||
if (len >= format_len) return BAD_FORMAT~;
|
||||
if (*args_index_ptr >= args_len) return BAD_FORMAT~;
|
||||
any val = args_ptr[(*args_index_ptr)++];
|
||||
if (!val.type.kindof.is_int()) return BAD_FORMAT?;
|
||||
if (!val.type.kindof.is_int()) return BAD_FORMAT~;
|
||||
uint? intval = types::any_to_int(val, int);
|
||||
return intval ?? BAD_FORMAT?;
|
||||
return intval ?? BAD_FORMAT~;
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ macro usz? readline_to_stream(out_stream, in_stream = io::stdin())
|
||||
if (catch err = c)
|
||||
{
|
||||
if (err == io::EOF) break;
|
||||
return err?;
|
||||
return err~;
|
||||
}
|
||||
if (c == '\r') continue;
|
||||
if (c == '\n') break;
|
||||
@@ -404,7 +404,7 @@ fn char[]? bprintf(char[] buffer, String format, args...) @maydiscard
|
||||
fn void? out_buffer_fn(void *data, char c) @private
|
||||
{
|
||||
BufferData *buffer_data = data;
|
||||
if (buffer_data.written >= buffer_data.buffer.len) return BUFFER_EXCEEDED?;
|
||||
if (buffer_data.written >= buffer_data.buffer.len) return BUFFER_EXCEEDED~;
|
||||
buffer_data.buffer[buffer_data.written++] = c;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,20 +11,20 @@ macro void? native_chdir(Path path)
|
||||
{
|
||||
switch (libc::errno())
|
||||
{
|
||||
case errno::EACCES: return io::NO_PERMISSION?;
|
||||
case errno::ENAMETOOLONG: return io::NAME_TOO_LONG?;
|
||||
case errno::ENOTDIR: return io::FILE_NOT_DIR?;
|
||||
case errno::ENOENT: return io::FILE_NOT_FOUND?;
|
||||
case errno::ELOOP: return io::SYMLINK_FAILED?;
|
||||
default: return io::GENERAL_ERROR?;
|
||||
case errno::EACCES: return io::NO_PERMISSION~;
|
||||
case errno::ENAMETOOLONG: return io::NAME_TOO_LONG~;
|
||||
case errno::ENOTDIR: return io::FILE_NOT_DIR~;
|
||||
case errno::ENOENT: return io::FILE_NOT_FOUND~;
|
||||
case errno::ELOOP: return io::SYMLINK_FAILED~;
|
||||
default: return io::GENERAL_ERROR~;
|
||||
}
|
||||
}
|
||||
$case env::WIN32:
|
||||
// TODO improve with better error handling.
|
||||
if (win32::setCurrentDirectoryW(path.str_view().to_temp_utf16()!!)) return;
|
||||
return io::GENERAL_ERROR?;
|
||||
return io::GENERAL_ERROR~;
|
||||
$default:
|
||||
return io::UNSUPPORTED_OPERATION?;
|
||||
return io::UNSUPPORTED_OPERATION~;
|
||||
$endswitch
|
||||
};
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ fn void*? native_fopen(String filename, String mode) @inline => @pool()
|
||||
$else
|
||||
void* file = libc::fopen(filename.zstr_tcopy(), mode.zstr_tcopy());
|
||||
$endif
|
||||
return file ?: file_open_errno()?;
|
||||
return file ?: file_open_errno()~;
|
||||
}
|
||||
|
||||
fn void? native_remove(String filename) => @pool()
|
||||
@@ -27,10 +27,10 @@ fn void? native_remove(String filename) => @pool()
|
||||
switch (libc::errno())
|
||||
{
|
||||
case errno::ENOENT:
|
||||
return io::FILE_NOT_FOUND?;
|
||||
return io::FILE_NOT_FOUND~;
|
||||
case errno::EACCES:
|
||||
default:
|
||||
return io::FILE_CANNOT_DELETE?;
|
||||
return io::FILE_CANNOT_DELETE~;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,19 +46,19 @@ fn void*? native_freopen(void* file, String filename, String mode) @inline => @p
|
||||
$else
|
||||
file = libc::freopen(filename.zstr_tcopy(), mode.zstr_tcopy(), file);
|
||||
$endif
|
||||
return file ?: file_open_errno()?;
|
||||
return file ?: file_open_errno()~;
|
||||
}
|
||||
|
||||
fn void? native_fseek(void* file, isz offset, Seek seek_mode) @inline
|
||||
{
|
||||
if (libc::fseek(file, (SeekIndex)offset, seek_mode.ordinal)) return file_seek_errno()?;
|
||||
if (libc::fseek(file, (SeekIndex)offset, seek_mode.ordinal)) return file_seek_errno()~;
|
||||
}
|
||||
|
||||
|
||||
fn usz? native_ftell(CFile file) @inline
|
||||
{
|
||||
long index = libc::ftell(file);
|
||||
return index >= 0 ? (usz)index : file_seek_errno()?;
|
||||
return index >= 0 ? (usz)index : file_seek_errno()~;
|
||||
}
|
||||
|
||||
fn usz? native_fwrite(CFile file, char[] buffer) @inline
|
||||
@@ -68,7 +68,7 @@ fn usz? native_fwrite(CFile file, char[] buffer) @inline
|
||||
|
||||
fn void? native_fputc(CInt c, CFile stream) @inline
|
||||
{
|
||||
if (libc::fputc(c, stream) == libc::EOF) return io::EOF?;
|
||||
if (libc::fputc(c, stream) == libc::EOF) return io::EOF~;
|
||||
}
|
||||
|
||||
fn usz? native_fread(CFile file, char[] buffer) @inline
|
||||
|
||||
@@ -28,7 +28,7 @@ FputcFn native_fputc_fn @weak @if(!$defined(native_fputc_fn));
|
||||
fn void*? native_fopen(String filename, String mode) @inline
|
||||
{
|
||||
if (native_fopen_fn) return native_fopen_fn(filename, mode);
|
||||
return io::UNSUPPORTED_OPERATION?;
|
||||
return io::UNSUPPORTED_OPERATION~;
|
||||
}
|
||||
|
||||
<*
|
||||
@@ -39,7 +39,7 @@ fn void*? native_fopen(String filename, String mode) @inline
|
||||
fn void? native_remove(String filename) @inline
|
||||
{
|
||||
if (native_remove_fn) return native_remove_fn(filename);
|
||||
return io::UNSUPPORTED_OPERATION?;
|
||||
return io::UNSUPPORTED_OPERATION~;
|
||||
}
|
||||
|
||||
<*
|
||||
@@ -49,35 +49,35 @@ fn void? native_remove(String filename) @inline
|
||||
fn void*? native_freopen(void* file, String filename, String mode) @inline
|
||||
{
|
||||
if (native_freopen_fn) return native_freopen_fn(file, filename, mode);
|
||||
return io::UNSUPPORTED_OPERATION?;
|
||||
return io::UNSUPPORTED_OPERATION~;
|
||||
}
|
||||
|
||||
fn void? native_fseek(void* file, isz offset, Seek seek_mode) @inline
|
||||
{
|
||||
if (native_fseek_fn) return native_fseek_fn(file, offset, seek_mode);
|
||||
return io::UNSUPPORTED_OPERATION?;
|
||||
return io::UNSUPPORTED_OPERATION~;
|
||||
}
|
||||
|
||||
fn usz? native_ftell(CFile file) @inline
|
||||
{
|
||||
if (native_ftell_fn) return native_ftell_fn(file);
|
||||
return io::UNSUPPORTED_OPERATION?;
|
||||
return io::UNSUPPORTED_OPERATION~;
|
||||
}
|
||||
|
||||
fn usz? native_fwrite(CFile file, char[] buffer) @inline
|
||||
{
|
||||
if (native_fwrite_fn) return native_fwrite_fn(file, buffer);
|
||||
return io::UNSUPPORTED_OPERATION?;
|
||||
return io::UNSUPPORTED_OPERATION~;
|
||||
}
|
||||
|
||||
fn usz? native_fread(CFile file, char[] buffer) @inline
|
||||
{
|
||||
if (native_fread_fn) return native_fread_fn(file, buffer);
|
||||
return io::UNSUPPORTED_OPERATION?;
|
||||
return io::UNSUPPORTED_OPERATION~;
|
||||
}
|
||||
|
||||
fn void? native_fputc(CInt c, CFile stream) @inline
|
||||
{
|
||||
if (native_fputc_fn) return native_fputc_fn(c, stream);
|
||||
return io::UNSUPPORTED_OPERATION?;
|
||||
return io::UNSUPPORTED_OPERATION~;
|
||||
}
|
||||
|
||||
@@ -14,25 +14,25 @@ fn void? native_stat(Stat* stat, String path) @if(env::DARWIN || env::LINUX || e
|
||||
switch (libc::errno())
|
||||
{
|
||||
case errno::EBADF:
|
||||
return io::FILE_NOT_VALID?;
|
||||
return io::FILE_NOT_VALID~;
|
||||
case errno::EFAULT:
|
||||
unreachable("Invalid stat");
|
||||
case errno::EIO:
|
||||
return io::GENERAL_ERROR?;
|
||||
return io::GENERAL_ERROR~;
|
||||
case errno::EACCES:
|
||||
return io::NO_PERMISSION?;
|
||||
return io::NO_PERMISSION~;
|
||||
case errno::ELOOP:
|
||||
return io::NO_PERMISSION?;
|
||||
return io::NO_PERMISSION~;
|
||||
case errno::ENAMETOOLONG:
|
||||
return io::NAME_TOO_LONG?;
|
||||
return io::NAME_TOO_LONG~;
|
||||
case errno::ENOENT:
|
||||
return io::FILE_NOT_FOUND?;
|
||||
return io::FILE_NOT_FOUND~;
|
||||
case errno::ENOTDIR:
|
||||
return io::FILE_NOT_DIR?;
|
||||
return io::FILE_NOT_DIR~;
|
||||
case errno::EOVERFLOW:
|
||||
return io::GENERAL_ERROR?;
|
||||
return io::GENERAL_ERROR~;
|
||||
default:
|
||||
return io::UNKNOWN_ERROR?;
|
||||
return io::UNKNOWN_ERROR~;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ macro String? getcwd(Allocator allocator)
|
||||
defer if (free) libc::free(res);
|
||||
if (!res)
|
||||
{
|
||||
if (libc::errno() != errno::ERANGE) return io::GENERAL_ERROR?;
|
||||
if (libc::errno() != errno::ERANGE) return io::GENERAL_ERROR~;
|
||||
res = win32::_wgetcwd(null, 0);
|
||||
free = true;
|
||||
}
|
||||
@@ -27,7 +27,7 @@ macro String? getcwd(Allocator allocator)
|
||||
if (!res)
|
||||
{
|
||||
// Improve error
|
||||
if (libc::errno() != errno::ERANGE) return io::GENERAL_ERROR?;
|
||||
if (libc::errno() != errno::ERANGE) return io::GENERAL_ERROR~;
|
||||
res = posix::getcwd(null, 0);
|
||||
free = true;
|
||||
}
|
||||
@@ -35,7 +35,7 @@ macro String? getcwd(Allocator allocator)
|
||||
return res.copy(allocator);
|
||||
|
||||
$default:
|
||||
return io::UNSUPPORTED_OPERATION?;
|
||||
return io::UNSUPPORTED_OPERATION~;
|
||||
$endswitch
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ fn PathList? native_ls(Path dir, bool no_dirs, bool no_symlinks, String mask, Al
|
||||
directory = posix::opendir(dir.str_view() ? dir.str_view().zstr_tcopy() : (ZString)".");
|
||||
};
|
||||
defer if (directory) posix::closedir(directory);
|
||||
if (!directory) return (path::is_dir(dir) ? io::CANNOT_READ_DIR : io::FILE_NOT_DIR)?;
|
||||
if (!directory) return (path::is_dir(dir) ? io::CANNOT_READ_DIR : io::FILE_NOT_DIR)~;
|
||||
Posix_dirent* entry;
|
||||
while ((entry = posix::readdir(directory)))
|
||||
{
|
||||
@@ -38,7 +38,7 @@ fn PathList? native_ls(Path dir, bool no_dirs, bool no_symlinks, String mask, Al
|
||||
WString result = dir.str_view().tconcat(`\*`).to_temp_wstring()!!;
|
||||
Win32_WIN32_FIND_DATAW find_data;
|
||||
Win32_HANDLE find = win32::findFirstFileW(result, &find_data);
|
||||
if (find == win32::INVALID_HANDLE_VALUE) return io::CANNOT_READ_DIR?;
|
||||
if (find == win32::INVALID_HANDLE_VALUE) return io::CANNOT_READ_DIR~;
|
||||
defer win32::findClose(find);
|
||||
do
|
||||
{
|
||||
|
||||
@@ -17,17 +17,17 @@ macro bool? native_mkdir(Path path, MkdirPermissions permissions)
|
||||
case errno::EACCES:
|
||||
case errno::EPERM:
|
||||
case errno::EROFS:
|
||||
case errno::EFAULT: return io::NO_PERMISSION?;
|
||||
case errno::ENAMETOOLONG: return io::NAME_TOO_LONG?;
|
||||
case errno::EFAULT: return io::NO_PERMISSION~;
|
||||
case errno::ENAMETOOLONG: return io::NAME_TOO_LONG~;
|
||||
case errno::EDQUOT:
|
||||
case errno::ENOSPC: return io::OUT_OF_SPACE?;
|
||||
case errno::ENOSPC: return io::OUT_OF_SPACE~;
|
||||
case errno::EISDIR:
|
||||
case errno::EEXIST: return false;
|
||||
case errno::ELOOP: return io::SYMLINK_FAILED?;
|
||||
case errno::ENOTDIR: return io::FILE_NOT_FOUND?;
|
||||
case errno::ENOENT: return io::PARENT_DIR_MISSING?;
|
||||
case errno::ELOOP: return io::SYMLINK_FAILED~;
|
||||
case errno::ENOTDIR: return io::FILE_NOT_FOUND~;
|
||||
case errno::ENOENT: return io::PARENT_DIR_MISSING~;
|
||||
default:
|
||||
return io::GENERAL_ERROR?;
|
||||
return io::GENERAL_ERROR~;
|
||||
}
|
||||
$case env::WIN32:
|
||||
// TODO security attributes
|
||||
@@ -35,18 +35,18 @@ macro bool? native_mkdir(Path path, MkdirPermissions permissions)
|
||||
switch (win32::getLastError())
|
||||
{
|
||||
case win32::ERROR_ACCESS_DENIED:
|
||||
return io::NO_PERMISSION?;
|
||||
return io::NO_PERMISSION~;
|
||||
case win32::ERROR_DISK_FULL:
|
||||
return io::OUT_OF_SPACE?;
|
||||
return io::OUT_OF_SPACE~;
|
||||
case win32::ERROR_ALREADY_EXISTS:
|
||||
return false;
|
||||
case win32::ERROR_PATH_NOT_FOUND:
|
||||
return io::FILE_NOT_FOUND?;
|
||||
return io::FILE_NOT_FOUND~;
|
||||
default:
|
||||
return io::GENERAL_ERROR?;
|
||||
return io::GENERAL_ERROR~;
|
||||
}
|
||||
$default:
|
||||
return io::UNSUPPORTED_OPERATION?;
|
||||
return io::UNSUPPORTED_OPERATION~;
|
||||
$endswitch
|
||||
};
|
||||
}
|
||||
@@ -13,36 +13,36 @@ macro bool? native_rmdir(Path path)
|
||||
if (!posix::rmdir(path.str_view().zstr_tcopy())) return true;
|
||||
switch (libc::errno())
|
||||
{
|
||||
case errno::EBUSY: return io::BUSY?;
|
||||
case errno::EBUSY: return io::BUSY~;
|
||||
case errno::EACCES:
|
||||
case errno::EPERM:
|
||||
case errno::EROFS:
|
||||
case errno::EFAULT: return io::NO_PERMISSION?;
|
||||
case errno::ENAMETOOLONG: return io::NAME_TOO_LONG?;
|
||||
case errno::EFAULT: return io::NO_PERMISSION~;
|
||||
case errno::ENAMETOOLONG: return io::NAME_TOO_LONG~;
|
||||
case errno::ENOTDIR:
|
||||
case errno::ENOENT: return false;
|
||||
case errno::ENOTEMPTY: return io::DIR_NOT_EMPTY?;
|
||||
case errno::ELOOP: return io::SYMLINK_FAILED?;
|
||||
default: return io::GENERAL_ERROR?;
|
||||
case errno::ENOTEMPTY: return io::DIR_NOT_EMPTY~;
|
||||
case errno::ELOOP: return io::SYMLINK_FAILED~;
|
||||
default: return io::GENERAL_ERROR~;
|
||||
}
|
||||
$case env::WIN32:
|
||||
if (win32::removeDirectoryW(path.str_view().to_temp_utf16()!!)) return true;
|
||||
switch (win32::getLastError())
|
||||
{
|
||||
case win32::ERROR_ACCESS_DENIED:
|
||||
return io::NO_PERMISSION?;
|
||||
return io::NO_PERMISSION~;
|
||||
case win32::ERROR_CURRENT_DIRECTORY:
|
||||
return io::BUSY?;
|
||||
return io::BUSY~;
|
||||
case win32::ERROR_DIR_NOT_EMPTY:
|
||||
return io::DIR_NOT_EMPTY?;
|
||||
return io::DIR_NOT_EMPTY~;
|
||||
case win32::ERROR_DIRECTORY:
|
||||
case win32::ERROR_PATH_NOT_FOUND:
|
||||
return false;
|
||||
default:
|
||||
return io::GENERAL_ERROR?;
|
||||
return io::GENERAL_ERROR~;
|
||||
}
|
||||
$default:
|
||||
return io::UNSUPPORTED_OPERATION?;
|
||||
return io::UNSUPPORTED_OPERATION~;
|
||||
$endswitch
|
||||
};
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ fn void? native_rmtree(Path dir)
|
||||
{
|
||||
DIRPtr directory = posix::opendir(dir.str_view().zstr_tcopy());
|
||||
defer if (directory) posix::closedir(directory);
|
||||
if (!directory) return path::is_dir(dir) ? io::CANNOT_READ_DIR? : io::FILE_NOT_DIR?;
|
||||
if (!directory) return path::is_dir(dir) ? io::CANNOT_READ_DIR~ : io::FILE_NOT_DIR~;
|
||||
Posix_dirent* entry;
|
||||
while ((entry = posix::readdir(directory)))
|
||||
{
|
||||
@@ -27,7 +27,7 @@ fn void? native_rmtree(Path dir)
|
||||
if (libc::remove(new_path.str_view().zstr_tcopy()))
|
||||
{
|
||||
// TODO improve
|
||||
return io::GENERAL_ERROR?;
|
||||
return io::GENERAL_ERROR~;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -44,7 +44,7 @@ fn void? native_rmtree(Path path)
|
||||
String s = path.str_view().tconcat("\\*");
|
||||
Win32_HANDLE find = win32::findFirstFileW(s.to_temp_utf16(), &find_data)!;
|
||||
|
||||
if (find == win32::INVALID_HANDLE_VALUE) return io::CANNOT_READ_DIR?;
|
||||
if (find == win32::INVALID_HANDLE_VALUE) return io::CANNOT_READ_DIR~;
|
||||
defer win32::findClose(find);
|
||||
do
|
||||
{
|
||||
|
||||
@@ -21,7 +21,7 @@ fn String? win32_get_known_folder_temp(Win32_REFKNOWNFOLDERID rfid) @private @if
|
||||
{
|
||||
Win32_PWSTR path;
|
||||
Win32_HRESULT res = win32::shGetKnownFolderPath(rfid, 0x00008000 /* KF_FLAG_CREATE */, null, &path);
|
||||
if (res) return io::PATH_COULD_NOT_BE_FOUND?;
|
||||
if (res) return io::PATH_COULD_NOT_BE_FOUND~;
|
||||
return string::from_wstring(tmem, (WString)path);
|
||||
}
|
||||
|
||||
@@ -38,11 +38,11 @@ fn Path? native_home_directory(Allocator allocator) => @pool()
|
||||
$case NETBSD:
|
||||
$case OPENBSD:
|
||||
$case HAIKU:
|
||||
return path::new(allocator, env::tget_var("HOME")) ?? io::PATH_COULD_NOT_BE_FOUND?;
|
||||
return path::new(allocator, env::tget_var("HOME")) ?? io::PATH_COULD_NOT_BE_FOUND~;
|
||||
$case WIN32:
|
||||
return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_PROFILE));
|
||||
$default:
|
||||
return io::PATH_COULD_NOT_BE_FOUND?;
|
||||
return io::PATH_COULD_NOT_BE_FOUND~;
|
||||
$endswitch
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ fn Path? native_user_directory(Allocator allocator, NativeSystemDir dir) => @poo
|
||||
case TEMPLATES: return path::new(allocator, posix::xdg_user_dir_lookup(tmem, "TEMPLATES"));
|
||||
case SAVED_GAMES:
|
||||
case SCREENSHOTS: nextcase;
|
||||
default: return io::PATH_COULD_NOT_BE_FOUND?;
|
||||
default: return io::PATH_COULD_NOT_BE_FOUND~;
|
||||
}
|
||||
$case IOS:
|
||||
$case MACOS:
|
||||
@@ -85,7 +85,7 @@ fn Path? native_user_directory(Allocator allocator, NativeSystemDir dir) => @poo
|
||||
case SAVED_GAMES:
|
||||
case SCREENSHOTS:
|
||||
case TEMPLATES: nextcase;
|
||||
default: return io::PATH_COULD_NOT_BE_FOUND?;
|
||||
default: return io::PATH_COULD_NOT_BE_FOUND~;
|
||||
}
|
||||
$case WIN32:
|
||||
switch (dir)
|
||||
@@ -100,10 +100,10 @@ fn Path? native_user_directory(Allocator allocator, NativeSystemDir dir) => @poo
|
||||
case SCREENSHOTS: return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_SCREENSHOTS));
|
||||
case TEMPLATES: return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_TEMPLATES));
|
||||
case PUBLIC_SHARE: nextcase;
|
||||
default: return io::PATH_COULD_NOT_BE_FOUND?;
|
||||
default: return io::PATH_COULD_NOT_BE_FOUND~;
|
||||
}
|
||||
$default:
|
||||
return io::PATH_COULD_NOT_BE_FOUND?;
|
||||
return io::PATH_COULD_NOT_BE_FOUND~;
|
||||
$endswitch
|
||||
}
|
||||
|
||||
@@ -121,16 +121,16 @@ fn Path? native_temp_directory(Allocator allocator) @if(!env::WIN32)
|
||||
fn Path? native_temp_directory(Allocator allocator) @if(env::WIN32) => @pool()
|
||||
{
|
||||
Win32_DWORD len = win32::getTempPathW(0, null);
|
||||
if (!len) return io::GENERAL_ERROR?;
|
||||
if (!len) return io::GENERAL_ERROR~;
|
||||
Char16[] buff = mem::talloc_array(Char16, len);
|
||||
Win32_DWORD res = win32::getTempPathW(len, buff);
|
||||
if (!res) return io::GENERAL_ERROR?;
|
||||
if (!res) return io::GENERAL_ERROR~;
|
||||
return path::new(allocator, string::tfrom_utf16(buff[:res]));
|
||||
}
|
||||
|
||||
module std::io::os @if(env::NO_LIBC);
|
||||
import std::io::path;
|
||||
|
||||
macro Path? native_home_directory(Allocator allocator) => io::PATH_COULD_NOT_BE_FOUND?;
|
||||
macro Path? native_temp_directory(Allocator allocator) => io::PATH_COULD_NOT_BE_FOUND?;
|
||||
fn Path? native_user_directory(Allocator allocator, NativeSystemDir dir) => io::PATH_COULD_NOT_BE_FOUND?;
|
||||
macro Path? native_home_directory(Allocator allocator) => io::PATH_COULD_NOT_BE_FOUND~;
|
||||
macro Path? native_temp_directory(Allocator allocator) => io::PATH_COULD_NOT_BE_FOUND~;
|
||||
fn Path? native_user_directory(Allocator allocator, NativeSystemDir dir) => io::PATH_COULD_NOT_BE_FOUND~;
|
||||
|
||||
@@ -86,7 +86,7 @@ fn PathList? ls(Allocator allocator, Path dir, bool no_dirs = false, bool no_sym
|
||||
$if $defined(os::native_ls):
|
||||
return os::native_ls(dir, no_dirs, no_symlinks, mask, allocator);
|
||||
$else
|
||||
return io::UNSUPPORTED_OPERATION?;
|
||||
return io::UNSUPPORTED_OPERATION~;
|
||||
$endif
|
||||
}
|
||||
|
||||
@@ -137,11 +137,11 @@ macro bool? rmdir(path)
|
||||
*>
|
||||
fn void? rmtree(Path path)
|
||||
{
|
||||
if (!path.path_string.len) return INVALID_PATH?;
|
||||
if (!path.path_string.len) return INVALID_PATH~;
|
||||
$if $defined(os::native_rmtree):
|
||||
return os::native_rmtree(path);
|
||||
$else
|
||||
return io::UNSUPPORTED_OPERATION?;
|
||||
return io::UNSUPPORTED_OPERATION~;
|
||||
$endif
|
||||
}
|
||||
|
||||
@@ -212,7 +212,7 @@ fn usz? start_of_base_name(String str, PathEnv path_env) @local
|
||||
// Find the \ before "foo"
|
||||
usz last_index = 2 + str[2..].index_of_char('\\')!;
|
||||
// If they don't match, we're done
|
||||
if (last_index > index) return INVALID_PATH?;
|
||||
if (last_index > index) return INVALID_PATH~;
|
||||
if (last_index != index) return index + 1;
|
||||
// Otherwise just default to the volume length.
|
||||
}
|
||||
@@ -246,7 +246,7 @@ fn Path? String.to_absolute_path(self, Allocator allocator) => @pool()
|
||||
fn Path? Path.absolute(self, Allocator allocator)
|
||||
{
|
||||
String path_str = self.str_view();
|
||||
if (!path_str.len) return INVALID_PATH?;
|
||||
if (!path_str.len) return INVALID_PATH~;
|
||||
if (self.is_absolute()!) return new(allocator, path_str, self.env);
|
||||
if (path_str == ".")
|
||||
{
|
||||
@@ -262,7 +262,7 @@ fn Path? Path.absolute(self, Allocator allocator)
|
||||
const usz BUFFER_LEN = 4096;
|
||||
WString buffer = (WString)mem::talloc_array(Char16, BUFFER_LEN);
|
||||
buffer = win32::_wfullpath(buffer, path_str.to_temp_wstring()!, BUFFER_LEN);
|
||||
if (!buffer) return INVALID_PATH?;
|
||||
if (!buffer) return INVALID_PATH~;
|
||||
return { string::from_wstring(allocator, buffer), WIN32, allocator };
|
||||
};
|
||||
$else
|
||||
@@ -371,10 +371,10 @@ fn usz? volume_name_len(String path, PathEnv path_env) @local
|
||||
base_found = i;
|
||||
continue;
|
||||
}
|
||||
if (is_reserved_win32_path_char(c)) return INVALID_PATH?;
|
||||
if (is_reserved_win32_path_char(c)) return INVALID_PATH~;
|
||||
}
|
||||
if (base_found > 0 && base_found + 1 < len) return len;
|
||||
return INVALID_PATH?;
|
||||
return INVALID_PATH~;
|
||||
case 'A'..'Z':
|
||||
case 'a'..'z':
|
||||
return path[1] == ':' ? 2 : 0;
|
||||
@@ -392,7 +392,7 @@ fn usz? volume_name_len(String path, PathEnv path_env) @local
|
||||
*>
|
||||
fn Path? Path.parent(self)
|
||||
{
|
||||
if (self.path_string.len == 1 && is_separator(self.path_string[0], self.env)) return NO_PARENT?;
|
||||
if (self.path_string.len == 1 && is_separator(self.path_string[0], self.env)) return NO_PARENT~;
|
||||
foreach_r(i, c : self.path_string)
|
||||
{
|
||||
if (is_separator(c, self.env))
|
||||
@@ -405,7 +405,7 @@ fn Path? Path.parent(self)
|
||||
// Handle C:\foo
|
||||
if (volume_len == i)
|
||||
{
|
||||
if (i + 1 == self.path_string.len) return NO_PARENT?;
|
||||
if (i + 1 == self.path_string.len) return NO_PARENT~;
|
||||
return { self.path_string[:i + 1], WIN32, null };
|
||||
}
|
||||
}
|
||||
@@ -413,7 +413,7 @@ fn Path? Path.parent(self)
|
||||
return { self.path_string[:i], self.env, null };
|
||||
}
|
||||
}
|
||||
return NO_PARENT?;
|
||||
return NO_PARENT~;
|
||||
}
|
||||
|
||||
fn String? normalize(String path_str, PathEnv path_env = DEFAULT_ENV)
|
||||
@@ -455,7 +455,7 @@ fn String? normalize(String path_str, PathEnv path_env = DEFAULT_ENV)
|
||||
|
||||
// The rest are names of the path elements, so check that the
|
||||
// characters are valid.
|
||||
if (is_reserved_path_char(c, path_env)) return INVALID_PATH?;
|
||||
if (is_reserved_path_char(c, path_env)) return INVALID_PATH~;
|
||||
|
||||
// If we have '.' after a separator
|
||||
if (c == '.' && previous_was_separator)
|
||||
@@ -488,7 +488,7 @@ fn String? normalize(String path_str, PathEnv path_env = DEFAULT_ENV)
|
||||
continue;
|
||||
case 2:
|
||||
// This is an error: /a/../..
|
||||
if (len == path_start && has_root) return INVALID_PATH?;
|
||||
if (len == path_start && has_root) return INVALID_PATH~;
|
||||
|
||||
// If this .. at the start, or after ../? If so, we just copy ..
|
||||
if (len == path_start ||
|
||||
@@ -657,21 +657,21 @@ macro bool is_reserved_path_char(char c, PathEnv path_env = DEFAULT_ENV)
|
||||
}
|
||||
fn bool? _mkdir(Path path, bool recursive = false, MkdirPermissions permissions = NORMAL) @private
|
||||
{
|
||||
if (!path.path_string.len) return INVALID_PATH?;
|
||||
if (!path.path_string.len) return INVALID_PATH~;
|
||||
if (is_dir(path)) return false;
|
||||
if (exists(path)) return io::FILE_NOT_DIR?;
|
||||
if (exists(path)) return io::FILE_NOT_DIR~;
|
||||
|
||||
if (recursive)
|
||||
{
|
||||
if (try parent = path.parent()) mkdir(parent, true, permissions)!;
|
||||
}
|
||||
if (!is_dir(path.parent()) ?? false) return io::CANNOT_READ_DIR?;
|
||||
if (!is_dir(path.parent()) ?? false) return io::CANNOT_READ_DIR~;
|
||||
|
||||
return os::native_mkdir(path, permissions);
|
||||
}
|
||||
|
||||
fn bool? _rmdir(Path path) @private
|
||||
{
|
||||
if (!path.path_string.len) return INVALID_PATH?;
|
||||
if (!path.path_string.len) return INVALID_PATH~;
|
||||
return os::native_rmdir(path);
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ macro usz? read_all(stream, char[] buffer)
|
||||
{
|
||||
if (buffer.len == 0) return 0;
|
||||
usz n = stream.read(buffer)!;
|
||||
if (n != buffer.len) return UNEXPECTED_EOF?;
|
||||
if (n != buffer.len) return UNEXPECTED_EOF~;
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ macro usz? write_all(stream, char[] buffer)
|
||||
{
|
||||
if (buffer.len == 0) return 0;
|
||||
usz n = stream.write(buffer)!;
|
||||
if (n != buffer.len) return INCOMPLETE_WRITE?;
|
||||
if (n != buffer.len) return INCOMPLETE_WRITE~;
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ macro usz? read_using_read_byte(s, char[] buffer)
|
||||
if (catch err = c)
|
||||
{
|
||||
if (err == io::EOF) return len;
|
||||
return err?;
|
||||
return err~;
|
||||
}
|
||||
*cptr = c;
|
||||
len++;
|
||||
@@ -160,7 +160,7 @@ macro char? read_byte_using_read(s)
|
||||
{
|
||||
char[1] buffer;
|
||||
usz read = s.read(&buffer)!;
|
||||
if (read != 1) return io::EOF?;
|
||||
if (read != 1) return io::EOF~;
|
||||
return buffer[0];
|
||||
}
|
||||
|
||||
@@ -205,12 +205,12 @@ macro usz? copy_through_buffer(InStream in, OutStream dst, char[] buffer) @local
|
||||
if (catch err = len)
|
||||
{
|
||||
if (err == io::EOF) return total_copied;
|
||||
return err?;
|
||||
return err~;
|
||||
}
|
||||
if (!len) return total_copied;
|
||||
usz written = dst.write(buffer[:len])!;
|
||||
total_copied += len;
|
||||
if (written != len) return INCOMPLETE_WRITE?;
|
||||
if (written != len) return INCOMPLETE_WRITE~;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,8 +232,8 @@ macro usz? read_varint(stream, x_ptr)
|
||||
char? c = stream.read_byte();
|
||||
if (catch err = c)
|
||||
{
|
||||
if (err == io::EOF) return io::UNEXPECTED_EOF?;
|
||||
return err?;
|
||||
if (err == io::EOF) return io::UNEXPECTED_EOF~;
|
||||
return err~;
|
||||
}
|
||||
n++;
|
||||
if (c & 0x80 == 0)
|
||||
@@ -249,7 +249,7 @@ macro usz? read_varint(stream, x_ptr)
|
||||
x |= (c & 0x7F) << shift;
|
||||
shift += 7;
|
||||
}
|
||||
return math::OVERFLOW?;
|
||||
return math::OVERFLOW~;
|
||||
}
|
||||
<*
|
||||
@require @is_outstream(stream)
|
||||
|
||||
@@ -49,7 +49,7 @@ fn usz? ReadBuffer.read(&self, char[] bytes) @dynamic
|
||||
fn char? ReadBuffer.read_byte(&self) @dynamic
|
||||
{
|
||||
if (self.read_idx == self.write_idx) self.refill()!;
|
||||
if (self.read_idx == self.write_idx) return io::EOF?;
|
||||
if (self.read_idx == self.write_idx) return io::EOF~;
|
||||
char c = self.bytes[self.read_idx];
|
||||
self.read_idx++;
|
||||
return c;
|
||||
@@ -132,5 +132,5 @@ fn void? WriteBuffer.write_byte(&self, char c) @dynamic
|
||||
fn void? WriteBuffer.write_pending(&self) @local
|
||||
{
|
||||
self.index -= self.wrapped_stream.write(self.bytes[:self.index])!;
|
||||
if (self.index != 0) return INCOMPLETE_WRITE?;
|
||||
if (self.index != 0) return INCOMPLETE_WRITE~;
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ fn usz? ByteBuffer.read(&self, char[] bytes) @dynamic
|
||||
if (readable == 0)
|
||||
{
|
||||
self.has_last = false;
|
||||
return io::EOF?;
|
||||
return io::EOF~;
|
||||
}
|
||||
usz n = min(readable, bytes.len);
|
||||
bytes[:n] = self.bytes[self.read_idx:n];
|
||||
@@ -84,7 +84,7 @@ fn char? ByteBuffer.read_byte(&self) @dynamic
|
||||
if (readable == 0)
|
||||
{
|
||||
self.has_last = false;
|
||||
return io::EOF?;
|
||||
return io::EOF~;
|
||||
}
|
||||
char c = self.bytes[self.read_idx];
|
||||
self.read_idx++;
|
||||
@@ -98,7 +98,7 @@ fn char? ByteBuffer.read_byte(&self) @dynamic
|
||||
*>
|
||||
fn void? ByteBuffer.pushback_byte(&self) @dynamic
|
||||
{
|
||||
if (!self.has_last) return io::EOF?;
|
||||
if (!self.has_last) return io::EOF~;
|
||||
assert(self.read_idx > 0);
|
||||
self.read_idx--;
|
||||
self.has_last = false;
|
||||
@@ -109,15 +109,15 @@ fn usz? ByteBuffer.seek(&self, isz offset, Seek seek) @dynamic
|
||||
switch (seek)
|
||||
{
|
||||
case SET:
|
||||
if (offset < 0 || offset > self.write_idx) return INVALID_POSITION?;
|
||||
if (offset < 0 || offset > self.write_idx) return INVALID_POSITION~;
|
||||
self.read_idx = offset;
|
||||
return offset;
|
||||
case CURSOR:
|
||||
if ((offset < 0 && self.read_idx < -offset) ||
|
||||
(offset > 0 && self.read_idx + offset > self.write_idx)) return INVALID_POSITION?;
|
||||
(offset > 0 && self.read_idx + offset > self.write_idx)) return INVALID_POSITION~;
|
||||
self.read_idx += offset;
|
||||
case END:
|
||||
if (offset < 0 || offset > self.write_idx) return INVALID_POSITION?;
|
||||
if (offset < 0 || offset > self.write_idx) return INVALID_POSITION~;
|
||||
self.read_idx = self.write_idx - offset;
|
||||
}
|
||||
return self.read_idx;
|
||||
|
||||
@@ -19,7 +19,7 @@ fn ByteReader* ByteReader.init(&self, char[] bytes)
|
||||
|
||||
fn usz? ByteReader.read(&self, char[] bytes) @dynamic
|
||||
{
|
||||
if (self.index >= self.bytes.len) return io::EOF?;
|
||||
if (self.index >= self.bytes.len) return io::EOF~;
|
||||
usz len = min(self.bytes.len - self.index, bytes.len);
|
||||
if (len == 0) return 0;
|
||||
mem::copy(bytes.ptr, &self.bytes[self.index], len);
|
||||
@@ -29,13 +29,13 @@ fn usz? ByteReader.read(&self, char[] bytes) @dynamic
|
||||
|
||||
fn char? ByteReader.read_byte(&self) @dynamic
|
||||
{
|
||||
if (self.index >= self.bytes.len) return io::EOF?;
|
||||
if (self.index >= self.bytes.len) return io::EOF~;
|
||||
return self.bytes[self.index++];
|
||||
}
|
||||
|
||||
fn void? ByteReader.pushback_byte(&self) @dynamic
|
||||
{
|
||||
if (!self.index) return INVALID_PUSHBACK?;
|
||||
if (!self.index) return INVALID_PUSHBACK~;
|
||||
self.index--;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ fn usz? ByteReader.seek(&self, isz offset, Seek seek) @dynamic
|
||||
case CURSOR: new_index = self.index + offset;
|
||||
case END: new_index = self.bytes.len + offset;
|
||||
}
|
||||
if (new_index < 0) return INVALID_POSITION?;
|
||||
if (new_index < 0) return INVALID_POSITION~;
|
||||
self.index = new_index;
|
||||
return new_index;
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ fn String ByteWriter.str_view(&self) @inline
|
||||
fn void? ByteWriter.ensure_capacity(&self, usz len) @inline
|
||||
{
|
||||
if (self.bytes.len > len) return;
|
||||
if (!self.allocator) return OUT_OF_SPACE?;
|
||||
if (!self.allocator) return OUT_OF_SPACE~;
|
||||
if (len < 16) len = 16;
|
||||
usz new_capacity = math::next_power_of_2(len);
|
||||
char* new_ptr = allocator::realloc_try(self.allocator, self.bytes.ptr, new_capacity)!;
|
||||
|
||||
@@ -24,7 +24,7 @@ fn void? LimitReader.close(&self) @dynamic
|
||||
|
||||
fn usz? LimitReader.read(&self, char[] bytes) @dynamic
|
||||
{
|
||||
if (self.limit == 0) return io::EOF?;
|
||||
if (self.limit == 0) return io::EOF~;
|
||||
usz m = min(bytes.len, self.limit);
|
||||
usz n = self.wrapped_stream.read(bytes[:m])!;
|
||||
self.limit -= n;
|
||||
@@ -33,7 +33,7 @@ fn usz? LimitReader.read(&self, char[] bytes) @dynamic
|
||||
|
||||
fn char? LimitReader.read_byte(&self) @dynamic
|
||||
{
|
||||
if (self.limit == 0) return io::EOF?;
|
||||
if (self.limit == 0) return io::EOF~;
|
||||
defer try self.limit--;
|
||||
return self.wrapped_stream.read_byte();
|
||||
}
|
||||
|
||||
@@ -49,11 +49,11 @@ fn usz? MultiReader.read(&self, char[] bytes) @dynamic
|
||||
usz? n = r.read(bytes);
|
||||
if (catch err = n)
|
||||
{
|
||||
if (err != io::EOF) return err?;
|
||||
if (err != io::EOF) return err~;
|
||||
self.index++;
|
||||
if (self.index >= self.readers.len)
|
||||
{
|
||||
return io::EOF?;
|
||||
return io::EOF~;
|
||||
}
|
||||
return self.read(bytes);
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ fn usz? MultiWriter.write(&self, char[] bytes) @dynamic
|
||||
foreach (w : self.writers)
|
||||
{
|
||||
n = w.write(bytes)!;
|
||||
if (n != bytes.len) return INCOMPLETE_WRITE?;
|
||||
if (n != bytes.len) return INCOMPLETE_WRITE~;
|
||||
}
|
||||
return bytes.len;
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ fn char[]? Scanner.scan(&self, String pattern = "\n")
|
||||
{
|
||||
// Split pattern not found with maximized search, abort.
|
||||
// Split pattern not found and already read as much as possible.
|
||||
return NOT_FOUND?;
|
||||
return NOT_FOUND~;
|
||||
}
|
||||
// Split pattern not found: maximize the search and try one more time.
|
||||
self.buf[:n] = buf[..];
|
||||
@@ -92,8 +92,8 @@ macro usz? Scanner.refill(&self, buf) @private
|
||||
usz? n = self.wrapped_stream.read(buf);
|
||||
if (catch err = n)
|
||||
{
|
||||
if (err == io::EOF) return NOT_FOUND?;
|
||||
return err?;
|
||||
if (err == io::EOF) return NOT_FOUND~;
|
||||
return err~;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ fn usz? TeeReader.read(&self, char[] bytes) @dynamic
|
||||
usz nr, nw;
|
||||
nr = self.r.read(bytes)!;
|
||||
nw = self.w.write(bytes[:nr])!;
|
||||
if (nr != nw) return GENERAL_ERROR?;
|
||||
if (nr != nw) return GENERAL_ERROR~;
|
||||
return nr;
|
||||
}
|
||||
|
||||
|
||||
@@ -102,9 +102,9 @@ fn BigInt*? BigInt.init_string_radix(&self, String value, int radix)
|
||||
case 'a'..'z':
|
||||
pos_val -= 'a' - 10;
|
||||
default:
|
||||
return string::MALFORMED_INTEGER?;
|
||||
return string::MALFORMED_INTEGER~;
|
||||
}
|
||||
if (pos_val >= radix) return string::MALFORMED_INTEGER?;
|
||||
if (pos_val >= radix) return string::MALFORMED_INTEGER~;
|
||||
if (limit == 1) pos_val = -pos_val;
|
||||
self.add_this(multiplier.mult(from_int(pos_val)));
|
||||
if (i - 1 >= limit)
|
||||
@@ -115,9 +115,9 @@ fn BigInt*? BigInt.init_string_radix(&self, String value, int radix)
|
||||
switch
|
||||
{
|
||||
case limit && !self.is_negative():
|
||||
return string::INTEGER_OVERFLOW?;
|
||||
return string::INTEGER_OVERFLOW~;
|
||||
case !limit && self.is_negative():
|
||||
return string::INTEGER_OVERFLOW?;
|
||||
return string::INTEGER_OVERFLOW~;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -1119,21 +1119,21 @@ fn float _frexpf(float x, int* e)
|
||||
macro overflow_add_helper(x, y) @local
|
||||
{
|
||||
$typeof(x) res @noinit;
|
||||
if ($$overflow_add(x, y, &res)) return OVERFLOW?;
|
||||
if ($$overflow_add(x, y, &res)) return OVERFLOW~;
|
||||
return res;
|
||||
}
|
||||
|
||||
macro overflow_sub_helper(x, y) @local
|
||||
{
|
||||
$typeof(x) res @noinit;
|
||||
if ($$overflow_sub(x, y, &res)) return OVERFLOW?;
|
||||
if ($$overflow_sub(x, y, &res)) return OVERFLOW~;
|
||||
return res;
|
||||
}
|
||||
|
||||
macro overflow_mul_helper(x, y) @local
|
||||
{
|
||||
$typeof(x) res @noinit;
|
||||
if ($$overflow_mul(x, y, &res)) return OVERFLOW?;
|
||||
if ($$overflow_mul(x, y, &res)) return OVERFLOW~;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -320,7 +320,7 @@ fn Matrix4x4 Matrix4x4.adjoint(&self)
|
||||
fn Matrix2x2? Matrix2x2.inverse(&self)
|
||||
{
|
||||
Real det = self.determinant();
|
||||
if (det == 0) return math::MATRIX_INVERSE_DOESNT_EXIST?;
|
||||
if (det == 0) return math::MATRIX_INVERSE_DOESNT_EXIST~;
|
||||
Matrix2x2 adj = self.adjoint();
|
||||
return adj.component_mul(1 / det).transpose();
|
||||
}
|
||||
@@ -328,7 +328,7 @@ fn Matrix2x2? Matrix2x2.inverse(&self)
|
||||
fn Matrix3x3? Matrix3x3.inverse(&self)
|
||||
{
|
||||
Real det = self.determinant();
|
||||
if (det == 0) return math::MATRIX_INVERSE_DOESNT_EXIST?;
|
||||
if (det == 0) return math::MATRIX_INVERSE_DOESNT_EXIST~;
|
||||
Matrix3x3 adj = self.adjoint();
|
||||
return adj.component_mul(1 / det).transpose();
|
||||
}
|
||||
@@ -336,7 +336,7 @@ fn Matrix3x3? Matrix3x3.inverse(&self)
|
||||
fn Matrix4x4? Matrix4x4.inverse(&self)
|
||||
{
|
||||
Real det = self.determinant();
|
||||
if (det == 0) return math::MATRIX_INVERSE_DOESNT_EXIST?;
|
||||
if (det == 0) return math::MATRIX_INVERSE_DOESNT_EXIST~;
|
||||
Matrix4x4 adj = self.adjoint();
|
||||
return adj.component_mul(1 / det).transpose();
|
||||
}
|
||||
|
||||
@@ -68,11 +68,11 @@ fn String InetAddress.to_tstring(&self)
|
||||
fn InetAddress? ipv6_from_str(String s)
|
||||
{
|
||||
uint sections = 0;
|
||||
if (s.len < 2) return INVALID_IP_STRING?;
|
||||
if (s.len < 2) return INVALID_IP_STRING~;
|
||||
foreach (c : s) if (c == ':') sections++;
|
||||
int zero_segment_len = s[0] == ':' || s[^1] == ':' ? 9 - sections : 8 - sections;
|
||||
if (zero_segment_len == 7 && s.len == 2) return { .is_ipv6 = true };
|
||||
if (zero_segment_len > 7) return INVALID_IP_STRING?;
|
||||
if (zero_segment_len > 7) return INVALID_IP_STRING~;
|
||||
usz index = 0;
|
||||
bool last_was_colon, found_zero;
|
||||
int current = -1;
|
||||
@@ -88,7 +88,7 @@ fn InetAddress? ipv6_from_str(String s)
|
||||
last_was_colon = true;
|
||||
continue;
|
||||
}
|
||||
if (current < 0 || current > 65535) return INVALID_IP_STRING?;
|
||||
if (current < 0 || current > 65535) return INVALID_IP_STRING~;
|
||||
addr.ipv6arr[index++].val = (ushort)current;
|
||||
current = -1;
|
||||
last_was_colon = true;
|
||||
@@ -96,9 +96,9 @@ fn InetAddress? ipv6_from_str(String s)
|
||||
}
|
||||
assert(current == -1);
|
||||
// Check that this is the first ::
|
||||
if (found_zero) return INVALID_IP_STRING?;
|
||||
if (found_zero) return INVALID_IP_STRING~;
|
||||
// Also check that the zeroed section is at least 2
|
||||
if (zero_segment_len < 2) return INVALID_IP_STRING?;
|
||||
if (zero_segment_len < 2) return INVALID_IP_STRING~;
|
||||
// Skip (will be zero by default
|
||||
index += zero_segment_len;
|
||||
found_zero = true;
|
||||
@@ -106,7 +106,7 @@ fn InetAddress? ipv6_from_str(String s)
|
||||
continue;
|
||||
}
|
||||
last_was_colon = false;
|
||||
if (index > 7 || !c.is_xdigit()) return INVALID_IP_STRING?;
|
||||
if (index > 7 || !c.is_xdigit()) return INVALID_IP_STRING~;
|
||||
if (current < 0) current = 0;
|
||||
current = current * 16 + (c <= '9' ? c - '0' : (c | 32) - 'a' + 10);
|
||||
}
|
||||
@@ -114,7 +114,7 @@ fn InetAddress? ipv6_from_str(String s)
|
||||
if (index == 8 && current == -1) return addr;
|
||||
|
||||
// Ends with number
|
||||
if (index != 7 || current < 0 || current > 65535) return INVALID_IP_STRING?;
|
||||
if (index != 7 || current < 0 || current > 65535) return INVALID_IP_STRING~;
|
||||
addr.ipv6arr[7].val = (ushort)current;
|
||||
return addr;
|
||||
}
|
||||
@@ -128,20 +128,20 @@ fn InetAddress? ipv4_from_str(String s)
|
||||
{
|
||||
if (c == '.')
|
||||
{
|
||||
if (current < 0) return INVALID_IP_STRING?;
|
||||
if (current > 255) return INVALID_IP_STRING?;
|
||||
if (current < 0) return INVALID_IP_STRING~;
|
||||
if (current > 255) return INVALID_IP_STRING~;
|
||||
switch (element)
|
||||
{
|
||||
case 0: addr.ipv4.a = (char)current;
|
||||
case 1: addr.ipv4.b = (char)current;
|
||||
case 2: addr.ipv4.c = (char)current;
|
||||
default: return INVALID_IP_STRING?;
|
||||
default: return INVALID_IP_STRING~;
|
||||
}
|
||||
current = -1;
|
||||
element++;
|
||||
continue;
|
||||
}
|
||||
if (element > 3 || c < '0' || c > '9') return INVALID_IP_STRING?;
|
||||
if (element > 3 || c < '0' || c > '9') return INVALID_IP_STRING~;
|
||||
if (current < 0)
|
||||
{
|
||||
current = c - '0';
|
||||
@@ -149,7 +149,7 @@ fn InetAddress? ipv4_from_str(String s)
|
||||
}
|
||||
current = current * 10 + c - '0';
|
||||
}
|
||||
if (element != 3 || current < 0 || current > 255) return INVALID_IP_STRING?;
|
||||
if (element != 3 || current < 0 || current > 255) return INVALID_IP_STRING~;
|
||||
addr.ipv4.d = (char)current;
|
||||
return addr;
|
||||
}
|
||||
@@ -258,6 +258,6 @@ fn AddrInfo*? addrinfo(String host, uint port, AIFamily ai_family, AISockType ai
|
||||
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 ADDRINFO_FAILED?;
|
||||
if (os::getaddrinfo(zhost, str.zstr_view(), &hints, &ai)) return ADDRINFO_FAILED~;
|
||||
return ai;
|
||||
}
|
||||
|
||||
@@ -37,13 +37,13 @@ fn uint? ipv4toint(String s)
|
||||
{
|
||||
if (c == '.')
|
||||
{
|
||||
if (current < 0) return INVALID_IP_STRING?;
|
||||
if (current < 0) return INVALID_IP_STRING~;
|
||||
out = out << 8 + current;
|
||||
current = -1;
|
||||
element++;
|
||||
continue;
|
||||
}
|
||||
if (element > 3 || c < '0' || c > '9') return INVALID_IP_STRING?;
|
||||
if (element > 3 || c < '0' || c > '9') return INVALID_IP_STRING~;
|
||||
if (current < 0)
|
||||
{
|
||||
current = c - '0';
|
||||
@@ -51,7 +51,7 @@ fn uint? ipv4toint(String s)
|
||||
}
|
||||
current = current * 10 + c - '0';
|
||||
}
|
||||
if (element != 3 || current < 0) return INVALID_IP_STRING?;
|
||||
if (element != 3 || current < 0) return INVALID_IP_STRING~;
|
||||
out = out << 8 + current;
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -66,8 +66,8 @@ macro void? NativeSocket.close(self)
|
||||
{
|
||||
if (libc::close(self))
|
||||
{
|
||||
if (libc::errno() == errno::EBADF) return net::INVALID_SOCKET?;
|
||||
return net::GENERAL_ERROR?;
|
||||
if (libc::errno() == errno::EBADF) return net::INVALID_SOCKET~;
|
||||
return net::GENERAL_ERROR~;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,8 +86,8 @@ macro void? NativeSocket.set_non_blocking(self, bool non_blocking)
|
||||
}
|
||||
if (fcntl(self, F_SETFL, flags) == -1)
|
||||
{
|
||||
if (libc::errno() == errno::EBADF) return net::INVALID_SOCKET?;
|
||||
return net::GENERAL_ERROR?;
|
||||
if (libc::errno() == errno::EBADF) return net::INVALID_SOCKET~;
|
||||
return net::GENERAL_ERROR~;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ macro void? start_wsa()
|
||||
if (wsa_error > 0)
|
||||
{
|
||||
mem::@atomic_store(wsa_init, 0);
|
||||
return os::socket_error()?;
|
||||
return os::socket_error()~;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -62,14 +62,14 @@ fn void? NativeSocket.set_non_blocking(self, bool non_blocking)
|
||||
{
|
||||
if (ioctlsocket(self, win32::FIONBIO, &&(CULong)non_blocking))
|
||||
{
|
||||
return socket_error()?;
|
||||
return socket_error()~;
|
||||
}
|
||||
}
|
||||
|
||||
macro void? NativeSocket.close(self)
|
||||
{
|
||||
WSAError error = closesocket(self);
|
||||
if (error) return convert_error(error)?;
|
||||
if (error) return convert_error(error)~;
|
||||
}
|
||||
|
||||
// https://github.com/wine-mirror/wine/blob/master/include/winsock.h
|
||||
|
||||
@@ -96,7 +96,7 @@ fn ulong? poll_ms(Poll[] polls, long timeout_ms)
|
||||
$else
|
||||
CInt result = os::poll((Posix_pollfd*)polls.ptr, (Posix_nfds_t)polls.len, (CInt)timeout_ms);
|
||||
$endif
|
||||
return result < 0 ? os::socket_error()? : (ulong)result;
|
||||
return result < 0 ? os::socket_error()~ : (ulong)result;
|
||||
}
|
||||
|
||||
macro Socket new_socket(fd, ai)
|
||||
@@ -133,7 +133,7 @@ fn void? Socket.set_option(&self, SocketOption option, bool value)
|
||||
{
|
||||
CInt flag = (CInt)value;
|
||||
int errcode = os::setsockopt(self.sock, os::SOL_SOCKET, option.value, &flag, CInt.sizeof);
|
||||
if (errcode != 0) return SOCKOPT_FAILED?;
|
||||
if (errcode != 0) return SOCKOPT_FAILED~;
|
||||
}
|
||||
|
||||
fn bool? Socket.get_option(&self, SocketOption option)
|
||||
@@ -141,7 +141,7 @@ fn bool? Socket.get_option(&self, SocketOption option)
|
||||
CInt flag;
|
||||
Socklen_t socklen = CInt.sizeof;
|
||||
int errcode = os::getsockopt(self.sock, os::SOL_SOCKET, option.value, &flag, &socklen);
|
||||
if (errcode != 0) return SOCKOPT_FAILED?;
|
||||
if (errcode != 0) return SOCKOPT_FAILED~;
|
||||
return (bool)flag;
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ $if env::WIN32:
|
||||
$else
|
||||
isz n = libc::recv(self.sock, bytes.ptr, bytes.len, 0);
|
||||
$endif
|
||||
if (n < 0) return os::socket_error()?;
|
||||
if (n < 0) return os::socket_error()~;
|
||||
return (usz)n;
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ $if env::WIN32:
|
||||
$else
|
||||
isz n = libc::send(self.sock, bytes.ptr, bytes.len, 0);
|
||||
$endif
|
||||
if (n < 0) return os::socket_error()?;
|
||||
if (n < 0) return os::socket_error()~;
|
||||
return (usz)n;
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ fn usz? Socket.peek(&self, char[] bytes) @dynamic
|
||||
$else
|
||||
isz n = libc::recv(self.sock, bytes.ptr, bytes.len, os::MSG_PEEK);
|
||||
$endif
|
||||
if (n < 0) return os::socket_error()?;
|
||||
if (n < 0) return os::socket_error()~;
|
||||
return (usz)n;
|
||||
}
|
||||
|
||||
@@ -202,6 +202,6 @@ fn void? Socket.shutdown(&self, SocketShutdownHow how)
|
||||
{
|
||||
if (libc::shutdown(self.sock, how.native_value) < 0)
|
||||
{
|
||||
return os::socket_error()?;
|
||||
return os::socket_error()~;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ fn Socket? connect_from_addrinfo(AddrInfo* addrinfo, SocketOption[] options) @pr
|
||||
// Keep the first successful connection.
|
||||
if (!errcode) return new_socket(sockfd, ai);
|
||||
};
|
||||
return os::socket_error()?;
|
||||
return os::socket_error()~;
|
||||
}
|
||||
|
||||
fn bool last_error_is_delayed_connect()
|
||||
@@ -67,7 +67,7 @@ fn Socket? connect_with_timeout_from_addrinfo(AddrInfo* addrinfo, SocketOption[]
|
||||
Duration to_remove = c.to_now().to_duration();
|
||||
if (to_remove >= timeout_left)
|
||||
{
|
||||
return CONNECTION_TIMED_OUT?;
|
||||
return CONNECTION_TIMED_OUT~;
|
||||
}
|
||||
timeout_left -= to_remove;
|
||||
}
|
||||
@@ -78,7 +78,7 @@ fn Socket? connect_with_timeout_from_addrinfo(AddrInfo* addrinfo, SocketOption[]
|
||||
Poll poll_request = { sockfd, SUBSCRIBE_ANY_WRITE, 0 };
|
||||
if (!poll((&poll_request)[:1], timeout_left)!)
|
||||
{
|
||||
return CONNECTION_TIMED_OUT?;
|
||||
return CONNECTION_TIMED_OUT~;
|
||||
}
|
||||
if (poll_request.revents & POLL_EVENT_WRITE)
|
||||
{
|
||||
@@ -87,7 +87,7 @@ fn Socket? connect_with_timeout_from_addrinfo(AddrInfo* addrinfo, SocketOption[]
|
||||
}
|
||||
}
|
||||
};
|
||||
return os::socket_error()?;
|
||||
return os::socket_error()~;
|
||||
}
|
||||
|
||||
fn Socket? connect_async_from_addrinfo(AddrInfo* addrinfo, SocketOption[] options) @private
|
||||
@@ -106,7 +106,7 @@ fn Socket? connect_async_from_addrinfo(AddrInfo* addrinfo, SocketOption[] option
|
||||
return new_socket(sockfd, ai);
|
||||
}
|
||||
};
|
||||
return os::socket_error()?;
|
||||
return os::socket_error()~;
|
||||
}
|
||||
|
||||
macro void @network_loop_over_ai(network, host, port; @body(fd, ai)) @private
|
||||
|
||||
@@ -53,7 +53,7 @@ fn TcpSocket? accept(TcpServerSocket* server_socket)
|
||||
os::start_wsa()!;
|
||||
$endif
|
||||
socket.sock = os::accept(server_socket.sock, (SockAddrPtr)&socket.ai_addr_storage, &socket.ai_addrlen);
|
||||
if (!socket.sock.is_valid()) return net::ACCEPT_FAILED?;
|
||||
if (!socket.sock.is_valid()) return net::ACCEPT_FAILED~;
|
||||
return socket;
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ fn TcpServerSocket? listen_to(AddrInfo* ai, uint backlog, SocketOption... option
|
||||
bool err = os::bind(sockfd, ai_candidate.ai_addr, ai_candidate.ai_addrlen) || os::listen(sockfd, backlog);
|
||||
if (!err) return (TcpServerSocket)net::new_socket(sockfd, ai_candidate);
|
||||
};
|
||||
return os::socket_error()?;
|
||||
return os::socket_error()~;
|
||||
}
|
||||
|
||||
struct TcpSocketPair
|
||||
@@ -88,7 +88,7 @@ fn TcpSocketPair*? TcpSocketPair.init(&self)
|
||||
listen_sock_info.ai_addrlen = listen_sock.ai_addr_storage.len;
|
||||
|
||||
int sock_result = os::getsockname(listen_sock.sock, (SockAddrPtr) &listen_sock_info.ai_addr_storage, &listen_sock_info.ai_addrlen);
|
||||
if (sock_result < 0) return os::socket_error()?;
|
||||
if (sock_result < 0) return os::socket_error()~;
|
||||
|
||||
char[] listen_port_bytes = listen_sock_info.ai_addr_storage[2:2];
|
||||
char msb = listen_port_bytes[0];
|
||||
@@ -102,7 +102,7 @@ fn TcpSocketPair*? TcpSocketPair.init(&self)
|
||||
$else
|
||||
NativeSocket[2] sockets;
|
||||
isz sockpair_result = os::socketpair(os::AF_UNIX, os::SOCK_STREAM, 0, &sockets);
|
||||
if (sockpair_result < 0) return os::socket_error()?;
|
||||
if (sockpair_result < 0) return os::socket_error()~;
|
||||
|
||||
Socket send_sock = { .sock = sockets[0] };
|
||||
TcpSocket tcp_send_sock = (TcpSocket) send_sock;
|
||||
|
||||
@@ -59,22 +59,22 @@ fn Url? tparse(String url_string) => parse(tmem, url_string);
|
||||
fn Url? parse(Allocator allocator, String url_string)
|
||||
{
|
||||
url_string = url_string.trim();
|
||||
if (!url_string) return EMPTY?;
|
||||
if (!url_string) return EMPTY~;
|
||||
Url url = { .allocator = allocator };
|
||||
|
||||
// Parse scheme
|
||||
if (try pos = url_string.index_of("://"))
|
||||
{
|
||||
if (!pos) return INVALID_SCHEME?;
|
||||
if (!pos) return INVALID_SCHEME~;
|
||||
url.scheme = url_string[:pos].copy(allocator);
|
||||
url_string = url_string[url.scheme.len + 3 ..];
|
||||
}
|
||||
else if (try pos = url_string.index_of(":"))
|
||||
{
|
||||
// Handle schemes without authority like 'mailto:'
|
||||
if (!pos) return INVALID_SCHEME?;
|
||||
if (!pos) return INVALID_SCHEME~;
|
||||
url.scheme = url_string[:pos].copy(allocator);
|
||||
url.path = decode(allocator, url_string[pos + 1 ..], PATH) ?? INVALID_PATH?!;
|
||||
url.path = decode(allocator, url_string[pos + 1 ..], PATH) ?? INVALID_PATH~!;
|
||||
return url;
|
||||
}
|
||||
|
||||
@@ -93,11 +93,11 @@ fn Url? parse(Allocator allocator, String url_string)
|
||||
{
|
||||
String[] userpass = userinfo.tsplit(":", 2);
|
||||
username = userpass[0];
|
||||
if (!username.len) return INVALID_USER?;
|
||||
if (!username.len) return INVALID_USER~;
|
||||
url.host =
|
||||
|
||||
url.username = decode(allocator, username, HOST) ?? INVALID_USER?!;
|
||||
if (userpass.len) url.password = decode(allocator, userpass[1], USERPASS) ?? INVALID_PASSWORD?!;
|
||||
url.username = decode(allocator, username, HOST) ?? INVALID_USER~!;
|
||||
if (userpass.len) url.password = decode(allocator, userpass[1], USERPASS) ?? INVALID_PASSWORD~!;
|
||||
};
|
||||
authority = authority[userinfo.len + 1 ..];
|
||||
}
|
||||
@@ -129,7 +129,7 @@ fn Url? parse(Allocator allocator, String url_string)
|
||||
}
|
||||
};
|
||||
}
|
||||
url.host = decode(allocator, host, HOST) ?? INVALID_HOST?!;
|
||||
url.host = decode(allocator, host, HOST) ?? INVALID_HOST~!;
|
||||
url_string = url_string[authority_end ..];
|
||||
}
|
||||
|
||||
@@ -140,12 +140,12 @@ fn Url? parse(Allocator allocator, String url_string)
|
||||
if (@ok(query_index) || @ok(fragment_index))
|
||||
{
|
||||
usz path_end = min(query_index ?? url_string.len, fragment_index ?? url_string.len);
|
||||
url.path = decode(allocator, url_string[:path_end], PATH) ?? INVALID_PATH?!;
|
||||
url.path = decode(allocator, url_string[:path_end], PATH) ?? INVALID_PATH~!;
|
||||
url_string = url_string[path_end ..];
|
||||
}
|
||||
else
|
||||
{
|
||||
url.path = decode(allocator, url_string, PATH) ?? INVALID_PATH?!;
|
||||
url.path = decode(allocator, url_string, PATH) ?? INVALID_PATH~!;
|
||||
url_string = "";
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ fn Url? parse(Allocator allocator, String url_string)
|
||||
// Parse fragment
|
||||
if (url_string.starts_with("#"))
|
||||
{
|
||||
url.fragment = decode(allocator, url_string[1..], FRAGMENT) ?? INVALID_FRAGMENT?!;
|
||||
url.fragment = decode(allocator, url_string[1..], FRAGMENT) ?? INVALID_FRAGMENT~!;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ fn usz? decode_len(String s, UrlEncodingMode mode) @inline
|
||||
if (c != '%') continue;
|
||||
if (i + 2 >= s.len || !s[i+1].is_xdigit() || !s[i+2].is_xdigit())
|
||||
{
|
||||
return INVALID_HEX?;
|
||||
return INVALID_HEX~;
|
||||
}
|
||||
n++;
|
||||
}
|
||||
|
||||
@@ -15,14 +15,14 @@ fn String? get_var(Allocator allocator, String name) => @pool()
|
||||
$switch:
|
||||
$case env::LIBC && !env::WIN32:
|
||||
ZString val = libc::getenv(name.zstr_tcopy());
|
||||
return val ? val.copy(allocator) : NOT_FOUND?;
|
||||
return val ? val.copy(allocator) : NOT_FOUND~;
|
||||
$case env::WIN32:
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getenvironmentvariable
|
||||
const usz BUFSIZE = 1024;
|
||||
WString buff = (WString)tcalloc(BUFSIZE * 2 + 2);
|
||||
WString wstr = name.to_temp_wstring()!;
|
||||
usz len = win32::getEnvironmentVariableW(wstr, buff, BUFSIZE);
|
||||
if (len == 0) return NOT_FOUND?;
|
||||
if (len == 0) return NOT_FOUND~;
|
||||
if (len > BUFSIZE)
|
||||
{
|
||||
buff = (WString)tmalloc(len * 2 + 2);
|
||||
@@ -122,6 +122,6 @@ fn String? executable_path()
|
||||
$if env::DARWIN:
|
||||
return darwin::executable_path();
|
||||
$else
|
||||
return NOT_FOUND?;
|
||||
return NOT_FOUND~;
|
||||
$endif
|
||||
}
|
||||
|
||||
@@ -181,17 +181,17 @@ fn ulong? elf_module_image_base(String path) @local
|
||||
defer (void)file.close();
|
||||
char[4] buffer;
|
||||
io::read_all(&file, &buffer)!;
|
||||
if (buffer != { 0x7f, 'E', 'L', 'F'}) return backtrace::IMAGE_NOT_FOUND?;
|
||||
if (buffer != { 0x7f, 'E', 'L', 'F'}) return backtrace::IMAGE_NOT_FOUND~;
|
||||
bool is_64 = file.read_byte()! == 2;
|
||||
bool is_little_endian = file.read_byte()! == 1;
|
||||
// Actually, not supported.
|
||||
if (!is_little_endian) return backtrace::IMAGE_NOT_FOUND?;
|
||||
if (!is_little_endian) return backtrace::IMAGE_NOT_FOUND~;
|
||||
file.seek(0)!;
|
||||
if (is_64)
|
||||
{
|
||||
Elf64_Ehdr file_header;
|
||||
io::read_any(&file, &file_header)!;
|
||||
if (file_header.e_ehsize != Elf64_Ehdr.sizeof) return backtrace::IMAGE_NOT_FOUND?;
|
||||
if (file_header.e_ehsize != Elf64_Ehdr.sizeof) return backtrace::IMAGE_NOT_FOUND~;
|
||||
for (isz i = 0; i < file_header.e_phnum; i++)
|
||||
{
|
||||
Elf64_Phdr header;
|
||||
@@ -203,7 +203,7 @@ fn ulong? elf_module_image_base(String path) @local
|
||||
}
|
||||
Elf32_Ehdr file_header;
|
||||
io::read_any(&file, &file_header)!;
|
||||
if (file_header.e_ehsize != Elf32_Ehdr.sizeof) return backtrace::IMAGE_NOT_FOUND?;
|
||||
if (file_header.e_ehsize != Elf32_Ehdr.sizeof) return backtrace::IMAGE_NOT_FOUND~;
|
||||
for (isz i = 0; i < file_header.e_phnum; i++)
|
||||
{
|
||||
Elf32_Phdr header;
|
||||
|
||||
@@ -87,7 +87,7 @@ fn String? executable_path()
|
||||
{
|
||||
char[4096] buf;
|
||||
uint temp_len = buf.len;
|
||||
if (darwin_NSGetExecutablePath(&buf, &temp_len) < 0) return NOT_FOUND?;
|
||||
if (darwin_NSGetExecutablePath(&buf, &temp_len) < 0) return NOT_FOUND~;
|
||||
len = (int)((ZString)&buf).len();
|
||||
path[:len] = buf[:len];
|
||||
}
|
||||
@@ -97,8 +97,8 @@ fn String? executable_path()
|
||||
fn uptr? load_address() @local
|
||||
{
|
||||
Darwin_segment_command_64* cmd = darwin::getsegbyname("__TEXT");
|
||||
if (!cmd) return backtrace::SEGMENT_NOT_FOUND?;
|
||||
String path = env::executable_path() ?? backtrace::EXECUTABLE_PATH_NOT_FOUND?!;
|
||||
if (!cmd) return backtrace::SEGMENT_NOT_FOUND~;
|
||||
String path = env::executable_path() ?? backtrace::EXECUTABLE_PATH_NOT_FOUND~!;
|
||||
uint dyld_count = darwin::_dyld_image_count();
|
||||
for (uint i = 0; i < dyld_count; i++)
|
||||
{
|
||||
@@ -107,7 +107,7 @@ fn uptr? load_address() @local
|
||||
if (image_name.str_view() != path) continue;
|
||||
return cmd.vmaddr + darwin::_dyld_get_image_vmaddr_slide(i);
|
||||
}
|
||||
return backtrace::IMAGE_NOT_FOUND?;
|
||||
return backtrace::IMAGE_NOT_FOUND~;
|
||||
}
|
||||
|
||||
fn Backtrace? backtrace_load_element(Allocator allocator, String execpath, void* buffer, void* load_address) @local
|
||||
|
||||
@@ -51,10 +51,10 @@ fn String? find_first_directory_temp(NSSearchPathDirectory directory, NSSearchPa
|
||||
objc::@autoreleasepool()
|
||||
{
|
||||
CFArrayRef arr = nsSearchPathForDirectoriesInDomains(directory, domainMask, true);
|
||||
if (!arr.getCount()) return io::PATH_COULD_NOT_BE_FOUND?;
|
||||
if (!arr.getCount()) return io::PATH_COULD_NOT_BE_FOUND~;
|
||||
CFStringRef str = (CFStringRef)arr.getValueAtIndex(0);
|
||||
char* buffer = tmalloc(2048);
|
||||
if (!str.getCString(buffer, 2048, UTF8)) return io::PATH_COULD_NOT_BE_FOUND?;
|
||||
if (!str.getCString(buffer, 2048, UTF8)) return io::PATH_COULD_NOT_BE_FOUND~;
|
||||
return ((ZString)buffer).str_view();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ alias NSInteger = $typefrom(env::ARCH_64_BIT ??? long : int);
|
||||
macro ObjcClass? class_by_name(ZString c)
|
||||
{
|
||||
ObjcClass cls = objc::lookUpClass(c);
|
||||
return cls ?: CLASS_NOT_FOUND?;
|
||||
return cls ?: CLASS_NOT_FOUND~;
|
||||
}
|
||||
|
||||
macro ObjcClass[] class_get_list(Allocator allocator)
|
||||
@@ -240,7 +240,7 @@ fn EventType? event_type_from(int val) @deprecated("Use NSEventType directly.")
|
||||
case EventType.PRESSURE.val: return PRESSURE;
|
||||
case EventType.DIRECT_TOUCH.val: return DIRECT_TOUCH;
|
||||
case EventType.CHANGE_MODE.val: return CHANGE_MODE;
|
||||
default: return objc::UNKNOWN_EVENT?;
|
||||
default: return objc::UNKNOWN_EVENT~;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ fn Backtrace? backtrace_line_parse(Allocator allocator, String obj, String addr2
|
||||
@stack_mem(256; Allocator mem)
|
||||
{
|
||||
String[] parts = addr2line.trim().split(mem, " at ");
|
||||
if (parts.len != 2) return NOT_FOUND?;
|
||||
if (parts.len != 2) return NOT_FOUND~;
|
||||
|
||||
uint line = 0;
|
||||
String source = "";
|
||||
|
||||
@@ -64,11 +64,11 @@ fn void? create_named_pipe_helper(void** rd, void **wr) @local @if(env::WIN32)
|
||||
win32::PIPE_ACCESS_INBOUND | win32::FILE_FLAG_OVERLAPPED,
|
||||
win32::PIPE_TYPE_BYTE | win32::PIPE_WAIT,
|
||||
1, 4096, 4096, 0, &sa_attr);
|
||||
if (win32::INVALID_HANDLE_VALUE == *rd) return FAILED_TO_CREATE_PIPE?;
|
||||
if (win32::INVALID_HANDLE_VALUE == *rd) return FAILED_TO_CREATE_PIPE~;
|
||||
*wr = win32::createFileA(
|
||||
str, win32::GENERIC_WRITE, 0, &sa_attr,
|
||||
win32::OPEN_EXISTING, win32::FILE_ATTRIBUTE_NORMAL, null);
|
||||
if (win32::INVALID_HANDLE_VALUE == *wr) return FAILED_TO_CREATE_PIPE?;
|
||||
if (win32::INVALID_HANDLE_VALUE == *wr) return FAILED_TO_CREATE_PIPE~;
|
||||
}
|
||||
|
||||
fn WString convert_command_line_win32(String[] command_line) @inline @if(env::WIN32) @local
|
||||
@@ -137,9 +137,9 @@ fn SubProcess? create(String[] command_line, SubProcessOptions options = {}, Str
|
||||
// Only create pipes if not inheriting stdio
|
||||
if (!options.inherit_stdio)
|
||||
{
|
||||
if (!win32::createPipe(&rd, &wr, &sa_attr, 0)) return FAILED_TO_CREATE_PIPE?;
|
||||
if (!win32::createPipe(&rd, &wr, &sa_attr, 0)) return FAILED_TO_CREATE_PIPE~;
|
||||
// TODO defer catch
|
||||
if (!win32::setHandleInformation(wr, win32::HANDLE_FLAG_INHERIT, 0)) return FAILED_TO_CREATE_PIPE?;
|
||||
if (!win32::setHandleInformation(wr, win32::HANDLE_FLAG_INHERIT, 0)) return FAILED_TO_CREATE_PIPE~;
|
||||
}
|
||||
|
||||
@stack_mem(2048; Allocator mem)
|
||||
@@ -168,7 +168,7 @@ fn SubProcess? create(String[] command_line, SubProcessOptions options = {}, Str
|
||||
if (fd != -1)
|
||||
{
|
||||
stdin = win32::_fdopen(fd, "wb");
|
||||
if (!stdin) return FAILED_TO_OPEN_STDIN?;
|
||||
if (!stdin) return FAILED_TO_OPEN_STDIN~;
|
||||
}
|
||||
start_info.hStdInput = rd;
|
||||
|
||||
@@ -179,15 +179,15 @@ fn SubProcess? create(String[] command_line, SubProcessOptions options = {}, Str
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!win32::createPipe(&rd, &wr, &sa_attr, 0)) return FAILED_TO_CREATE_PIPE?;
|
||||
if (!win32::createPipe(&rd, &wr, &sa_attr, 0)) return FAILED_TO_CREATE_PIPE~;
|
||||
}
|
||||
if (!win32::setHandleInformation(rd, win32::HANDLE_FLAG_INHERIT, 0)) return FAILED_TO_CREATE_PIPE?;
|
||||
if (!win32::setHandleInformation(rd, win32::HANDLE_FLAG_INHERIT, 0)) return FAILED_TO_CREATE_PIPE~;
|
||||
|
||||
fd = win32::_open_osfhandle((iptr)rd, 0);
|
||||
if (fd != -1)
|
||||
{
|
||||
stdout = win32::_fdopen(fd, "rb");
|
||||
if (!stdout) return FAILED_TO_OPEN_STDOUT?;
|
||||
if (!stdout) return FAILED_TO_OPEN_STDOUT~;
|
||||
}
|
||||
|
||||
start_info.hStdOutput = wr;
|
||||
@@ -207,15 +207,15 @@ fn SubProcess? create(String[] command_line, SubProcessOptions options = {}, Str
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!win32::createPipe(&rd, &wr, &sa_attr, 0)) return FAILED_TO_CREATE_PIPE?;
|
||||
if (!win32::createPipe(&rd, &wr, &sa_attr, 0)) return FAILED_TO_CREATE_PIPE~;
|
||||
}
|
||||
if (!win32::setHandleInformation(rd, win32::HANDLE_FLAG_INHERIT, 0)) return FAILED_TO_CREATE_PIPE?;
|
||||
if (!win32::setHandleInformation(rd, win32::HANDLE_FLAG_INHERIT, 0)) return FAILED_TO_CREATE_PIPE~;
|
||||
|
||||
fd = win32::_open_osfhandle((iptr)rd, 0);
|
||||
if (fd != -1)
|
||||
{
|
||||
stderr = win32::_fdopen(fd, "rb");
|
||||
if (!stderr) return FAILED_TO_OPEN_STDERR?;
|
||||
if (!stderr) return FAILED_TO_OPEN_STDERR~;
|
||||
}
|
||||
start_info.hStdError = wr;
|
||||
};
|
||||
@@ -239,7 +239,7 @@ fn SubProcess? create(String[] command_line, SubProcessOptions options = {}, Str
|
||||
used_environment, // environment
|
||||
null, // use parent dir
|
||||
&start_info, // startup info ptr
|
||||
&process_info)) return FAILED_TO_START_PROCESS?;
|
||||
&process_info)) return FAILED_TO_START_PROCESS~;
|
||||
};
|
||||
|
||||
// We don't need the handle of the primary thread in the called process.
|
||||
@@ -311,29 +311,29 @@ fn SubProcess? create(String[] command_line, SubProcessOptions options = {}, Str
|
||||
CFile stderr = null;
|
||||
|
||||
Posix_spawn_file_actions_t actions;
|
||||
if (posix::spawn_file_actions_init(&actions)) return FAILED_TO_INITIALIZE_ACTIONS?;
|
||||
if (posix::spawn_file_actions_init(&actions)) return FAILED_TO_INITIALIZE_ACTIONS~;
|
||||
defer posix::spawn_file_actions_destroy(&actions);
|
||||
|
||||
// Only set up pipes if not inheriting stdio
|
||||
if (!options.inherit_stdio)
|
||||
{
|
||||
if (posix::pipe(&stdinfd)) return FAILED_TO_OPEN_STDIN?;
|
||||
if (posix::pipe(&stdoutfd)) return FAILED_TO_OPEN_STDOUT?;
|
||||
if (!options.combined_stdout_stderr && posix::pipe(&stderrfd)) return FAILED_TO_OPEN_STDERR?;
|
||||
if (posix::pipe(&stdinfd)) return FAILED_TO_OPEN_STDIN~;
|
||||
if (posix::pipe(&stdoutfd)) return FAILED_TO_OPEN_STDOUT~;
|
||||
if (!options.combined_stdout_stderr && posix::pipe(&stderrfd)) return FAILED_TO_OPEN_STDERR~;
|
||||
|
||||
if (posix::spawn_file_actions_addclose(&actions, stdinfd[1])) return FAILED_TO_OPEN_STDIN?;
|
||||
if (posix::spawn_file_actions_adddup2(&actions, stdinfd[0], libc::STDIN_FD)) return FAILED_TO_OPEN_STDIN?;
|
||||
if (posix::spawn_file_actions_addclose(&actions, stdoutfd[0])) return FAILED_TO_OPEN_STDOUT?;
|
||||
if (posix::spawn_file_actions_adddup2(&actions, stdoutfd[1], libc::STDOUT_FD)) return FAILED_TO_OPEN_STDOUT?;
|
||||
if (posix::spawn_file_actions_addclose(&actions, stdinfd[1])) return FAILED_TO_OPEN_STDIN~;
|
||||
if (posix::spawn_file_actions_adddup2(&actions, stdinfd[0], libc::STDIN_FD)) return FAILED_TO_OPEN_STDIN~;
|
||||
if (posix::spawn_file_actions_addclose(&actions, stdoutfd[0])) return FAILED_TO_OPEN_STDOUT~;
|
||||
if (posix::spawn_file_actions_adddup2(&actions, stdoutfd[1], libc::STDOUT_FD)) return FAILED_TO_OPEN_STDOUT~;
|
||||
|
||||
if (options.combined_stdout_stderr)
|
||||
{
|
||||
if (posix::spawn_file_actions_adddup2(&actions, libc::STDOUT_FD, libc::STDERR_FD)) return FAILED_TO_OPEN_STDERR?;
|
||||
if (posix::spawn_file_actions_adddup2(&actions, libc::STDOUT_FD, libc::STDERR_FD)) return FAILED_TO_OPEN_STDERR~;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (posix::spawn_file_actions_addclose(&actions, stderrfd[0])) return FAILED_TO_OPEN_STDERR?;
|
||||
if (posix::spawn_file_actions_adddup2(&actions, stderrfd[1], libc::STDERR_FD)) return FAILED_TO_OPEN_STDERR?;
|
||||
if (posix::spawn_file_actions_addclose(&actions, stderrfd[0])) return FAILED_TO_OPEN_STDERR~;
|
||||
if (posix::spawn_file_actions_adddup2(&actions, stderrfd[1], libc::STDERR_FD)) return FAILED_TO_OPEN_STDERR~;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,11 +344,11 @@ fn SubProcess? create(String[] command_line, SubProcessOptions options = {}, Str
|
||||
ZString* used_environment = options.inherit_environment ? posix::environ : copy_env(mem, environment);
|
||||
if (options.search_user_path)
|
||||
{
|
||||
if (posix::spawnp(&child, command_line_copy[0], &actions, null, command_line_copy, used_environment)) return FAILED_TO_START_PROCESS?;
|
||||
if (posix::spawnp(&child, command_line_copy[0], &actions, null, command_line_copy, used_environment)) return FAILED_TO_START_PROCESS~;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (posix::spawnp(&child, command_line_copy[0], &actions, null, command_line_copy, used_environment)) return FAILED_TO_START_PROCESS?;
|
||||
if (posix::spawnp(&child, command_line_copy[0], &actions, null, command_line_copy, used_environment)) return FAILED_TO_START_PROCESS~;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -389,7 +389,7 @@ fn CInt? SubProcess.join(&self) @if(env::POSIX)
|
||||
self.stdin_file = null;
|
||||
}
|
||||
CInt status;
|
||||
if (self.child && self.child != posix::waitpid(self.child, &status, 0)) return PROCESS_JOIN_FAILED?;
|
||||
if (self.child && self.child != posix::waitpid(self.child, &status, 0)) return PROCESS_JOIN_FAILED~;
|
||||
|
||||
self.child = 0;
|
||||
self.is_alive = false;
|
||||
@@ -423,7 +423,7 @@ fn CInt? SubProcess.join(&self) @if(env::WIN32)
|
||||
}
|
||||
win32::waitForSingleObject(self.hProcess, win32::INFINITE);
|
||||
Win32_DWORD return_code @noinit;
|
||||
if (!win32::getExitCodeProcess(self.hProcess, &return_code)) return PROCESS_JOIN_FAILED?;
|
||||
if (!win32::getExitCodeProcess(self.hProcess, &return_code)) return PROCESS_JOIN_FAILED~;
|
||||
self.is_alive = false;
|
||||
return return_code;
|
||||
}
|
||||
@@ -450,9 +450,9 @@ fn bool SubProcess.destroy(&self)
|
||||
fn void? SubProcess.terminate(&self)
|
||||
{
|
||||
$if env::WIN32:
|
||||
if (!win32::terminateProcess(self.hProcess, 99)) return PROCESS_TERMINATION_FAILED?;
|
||||
if (!win32::terminateProcess(self.hProcess, 99)) return PROCESS_TERMINATION_FAILED~;
|
||||
$else
|
||||
if (posix::kill(self.child, 9)) return PROCESS_TERMINATION_FAILED?;
|
||||
if (posix::kill(self.child, 9)) return PROCESS_TERMINATION_FAILED~;
|
||||
$endif
|
||||
}
|
||||
|
||||
@@ -478,7 +478,7 @@ fn usz? read_from_file_win32(CFile file, Win32_HANDLE event_handle, char* buffer
|
||||
case win32::ERROR_HANDLE_EOF:
|
||||
break;
|
||||
default:
|
||||
return READ_FAILED?;
|
||||
return READ_FAILED~;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -488,7 +488,7 @@ fn usz? read_from_file_win32(CFile file, Win32_HANDLE event_handle, char* buffer
|
||||
fn usz? read_from_file_posix(CFile file, char* buffer, usz size) @if(env::POSIX) @local
|
||||
{
|
||||
isz bytes_read = libc::read(libc::fileno(file), buffer, size);
|
||||
if (bytes_read < 0) return READ_FAILED?;
|
||||
if (bytes_read < 0) return READ_FAILED~;
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
@@ -536,6 +536,6 @@ fn bool? SubProcess.is_running(&self)
|
||||
|
||||
fn usz? SubProcess.write_to_stdin(&self, char[] buffer)
|
||||
{
|
||||
if (!self.stdin_file) return FAILED_TO_OPEN_STDIN?;
|
||||
if (!self.stdin_file) return FAILED_TO_OPEN_STDIN~;
|
||||
return os::native_fwrite(self.stdin_file, buffer);
|
||||
}
|
||||
|
||||
@@ -130,9 +130,9 @@ fn Win32_DWORD? load_modules()
|
||||
Win32_HMODULE[1024] mod_buffer;
|
||||
if (!enumProcessModules(process, &mod_buffer, mod_buffer.len, &needed))
|
||||
{
|
||||
return backtrace::RESOLUTION_FAILED?;
|
||||
return backtrace::RESOLUTION_FAILED~;
|
||||
}
|
||||
if (needed > mod_buffer.len) return backtrace::RESOLUTION_FAILED?;
|
||||
if (needed > mod_buffer.len) return backtrace::RESOLUTION_FAILED~;
|
||||
Win32_HMODULE[] modules = mod_buffer[:needed];
|
||||
void* base = null;
|
||||
foreach (mod : modules)
|
||||
@@ -140,7 +140,7 @@ fn Win32_DWORD? load_modules()
|
||||
Win32_MODULEINFO info;
|
||||
if (!getModuleInformation(process, mod, &info, $sizeof(info)))
|
||||
{
|
||||
return backtrace::RESOLUTION_FAILED?;
|
||||
return backtrace::RESOLUTION_FAILED~;
|
||||
}
|
||||
if (!base) base = info.lpBaseOfDll;
|
||||
Win32_DWORD load_size = info.sizeOfImage;
|
||||
@@ -152,7 +152,7 @@ fn Win32_DWORD? load_modules()
|
||||
if (len2 < 1) continue;
|
||||
Win32_DWORD64 base_addr = symLoadModuleEx(process, null, (Win32_PCSTR)&char_buf, (Win32_PCSTR)&module_name, (Win32_DWORD64)info.lpBaseOfDll, load_size, null, 0);
|
||||
}
|
||||
if (!base) return backtrace::IMAGE_NOT_FOUND?;
|
||||
if (!base) return backtrace::IMAGE_NOT_FOUND~;
|
||||
Win32_IMAGE_NT_HEADERS* h = imageNtHeader(base);
|
||||
return h.fileHeader.machine;
|
||||
}
|
||||
@@ -187,13 +187,13 @@ fn Backtrace? resolve_backtrace(Allocator allocator, void* addr, Win32_HANDLE pr
|
||||
symbol.maxNameLen = 255;
|
||||
if (!symFromAddr(process, (Win32_DWORD64)addr - 1, &displacement, &symbol))
|
||||
{
|
||||
return backtrace::NO_BACKTRACE_SYMBOLS?;
|
||||
return backtrace::NO_BACKTRACE_SYMBOLS~;
|
||||
}
|
||||
Win32_IMAGEHLP_MODULE64 module_info;
|
||||
module_info.sizeOfStruct = Win32_IMAGEHLP_MODULE64.sizeof;
|
||||
if (!symGetModuleInfo64(process, (Win32_DWORD64)addr - 1, &module_info))
|
||||
{
|
||||
return backtrace::NO_BACKTRACE_SYMBOLS?;
|
||||
return backtrace::NO_BACKTRACE_SYMBOLS~;
|
||||
}
|
||||
ZString module_name = (ZString)&module_info.imageName;
|
||||
char[256] name;
|
||||
|
||||
@@ -49,5 +49,5 @@ fn String? xdg_user_dir_lookup(Allocator allocator, String type) => @pool()
|
||||
}
|
||||
return line.copy(allocator);
|
||||
}
|
||||
return io::PATH_COULD_NOT_BE_FOUND?;
|
||||
return io::PATH_COULD_NOT_BE_FOUND~;
|
||||
}
|
||||
@@ -120,7 +120,7 @@ fn ElementType? qselect(ListType list, isz low, isz high, isz k, CmpFn cmp, Cont
|
||||
}
|
||||
}
|
||||
}
|
||||
return NOT_FOUND?;
|
||||
return NOT_FOUND~;
|
||||
}
|
||||
|
||||
macro isz @partition(ListType list, isz l, isz h, CmpFn cmp, Context context)
|
||||
|
||||
@@ -73,7 +73,7 @@ fn void? BufferedChannel.push(self, Type val)
|
||||
}
|
||||
|
||||
// check if channel is closed
|
||||
if (channel.closed) return thread::CHANNEL_CLOSED?;
|
||||
if (channel.closed) return thread::CHANNEL_CLOSED~;
|
||||
|
||||
// save value to buf
|
||||
channel.buf[channel.sendx] = val;
|
||||
@@ -115,7 +115,7 @@ fn Type? BufferedChannel.pop(self)
|
||||
// check if chan is closed and empty
|
||||
if (channel.closed && channel.elems == 0)
|
||||
{
|
||||
return thread::CHANNEL_CLOSED?;
|
||||
return thread::CHANNEL_CLOSED~;
|
||||
}
|
||||
|
||||
// read from buf
|
||||
|
||||
@@ -137,7 +137,7 @@ fn void? FixedThreadPool.push(&self, ThreadPoolFn func, args...)
|
||||
{
|
||||
self.mu.lock();
|
||||
defer self.mu.unlock();
|
||||
if (self.qindex == self.queue.len) return thread::THREAD_QUEUE_FULL?;
|
||||
if (self.qindex == self.queue.len) return thread::THREAD_QUEUE_FULL~;
|
||||
any[] data;
|
||||
if (args.len)
|
||||
{
|
||||
|
||||
@@ -15,13 +15,13 @@ fn void NativeOnceFlag.call_once(&flag, OnceFn func)
|
||||
}
|
||||
}
|
||||
|
||||
fn void? NativeMutex.init(&mtx, MutexType type) => NOT_IMPLEMENTED?;
|
||||
fn void? NativeMutex.init(&mtx, MutexType type) => NOT_IMPLEMENTED~;
|
||||
|
||||
fn bool NativeMutex.is_initialized(&self)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
macro void NativeMutex.lock(&mutex) => NOT_IMPLEMENTED?!!;
|
||||
macro bool NativeMutex.try_lock(&mutex) => NOT_IMPLEMENTED?!!;
|
||||
macro void NativeMutex.unlock(&mutex) => NOT_IMPLEMENTED?!!;
|
||||
macro void NativeMutex.lock(&mutex) => NOT_IMPLEMENTED~!!;
|
||||
macro bool NativeMutex.try_lock(&mutex) => NOT_IMPLEMENTED~!!;
|
||||
macro void NativeMutex.unlock(&mutex) => NOT_IMPLEMENTED~!!;
|
||||
@@ -31,20 +31,20 @@ alias NativeOnceFlag = Pthread_once_t;
|
||||
fn void? NativeMutex.init(&self, MutexType type)
|
||||
{
|
||||
Pthread_mutexattr_t attr;
|
||||
if (posix::pthread_mutexattr_init(&attr)) return thread::INIT_FAILED?;
|
||||
if (posix::pthread_mutexattr_init(&attr)) return thread::INIT_FAILED~;
|
||||
defer posix::pthread_mutexattr_destroy(&attr);
|
||||
// TODO: make a fine grained error instead
|
||||
if (type.recursive)
|
||||
{
|
||||
if (posix::pthread_mutexattr_settype(&attr, posix::PTHREAD_MUTEX_RECURSIVE)) return thread::INIT_FAILED?;
|
||||
if (posix::pthread_mutexattr_settype(&attr, posix::PTHREAD_MUTEX_RECURSIVE)) return thread::INIT_FAILED~;
|
||||
}
|
||||
else
|
||||
{
|
||||
$if env::COMPILER_SAFE_MODE:
|
||||
if (posix::pthread_mutexattr_settype(&attr, posix::PTHREAD_MUTEX_ERRORCHECK)) return thread::INIT_FAILED?;
|
||||
if (posix::pthread_mutexattr_settype(&attr, posix::PTHREAD_MUTEX_ERRORCHECK)) return thread::INIT_FAILED~;
|
||||
$endif
|
||||
}
|
||||
if (posix::pthread_mutex_init(&self.mutex, &attr)) return thread::INIT_FAILED?;
|
||||
if (posix::pthread_mutex_init(&self.mutex, &attr)) return thread::INIT_FAILED~;
|
||||
self.initialized = true;
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ fn void? NativeMutex.lock_timeout(&self, ulong ms)
|
||||
{
|
||||
if (!ms) break;
|
||||
ulong sleep = min(5, ms);
|
||||
if (!libc::nanosleep(&&time::ms(ms).to_timespec(), null)) return thread::LOCK_TIMEOUT?;
|
||||
if (!libc::nanosleep(&&time::ms(ms).to_timespec(), null)) return thread::LOCK_TIMEOUT~;
|
||||
ms -= sleep;
|
||||
}
|
||||
switch (result)
|
||||
@@ -97,7 +97,7 @@ fn void? NativeMutex.lock_timeout(&self, ulong ms)
|
||||
return;
|
||||
case errno::EBUSY:
|
||||
case errno::ETIMEDOUT:
|
||||
return thread::LOCK_TIMEOUT?;
|
||||
return thread::LOCK_TIMEOUT~;
|
||||
default:
|
||||
return unreachable("Invalid lock %d", result);
|
||||
}
|
||||
@@ -121,7 +121,7 @@ fn void NativeMutex.unlock(&self)
|
||||
|
||||
fn void? NativeConditionVariable.init(&cond)
|
||||
{
|
||||
if (posix::pthread_cond_init(cond, null)) return thread::INIT_FAILED?;
|
||||
if (posix::pthread_cond_init(cond, null)) return thread::INIT_FAILED~;
|
||||
}
|
||||
|
||||
fn void NativeConditionVariable.destroy(&cond)
|
||||
@@ -163,7 +163,7 @@ fn void? NativeConditionVariable.wait_timeout(&cond, NativeMutex* mtx, ulong ms)
|
||||
*>
|
||||
fn void? NativeConditionVariable.wait_timeout_duration(&cond, NativeMutex* mtx, Duration duration)
|
||||
{
|
||||
if (duration < time::DURATION_ZERO) return thread::WAIT_TIMEOUT?;
|
||||
if (duration < time::DURATION_ZERO) return thread::WAIT_TIMEOUT~;
|
||||
Time time = time::now() + duration;
|
||||
return cond.wait_until(mtx, time) @inline;
|
||||
}
|
||||
@@ -177,13 +177,13 @@ fn void? NativeConditionVariable.wait_until(&cond, NativeMutex* mtx, Time time)
|
||||
switch (posix::pthread_cond_timedwait(cond, &mtx.mutex, &&time.to_timespec()))
|
||||
{
|
||||
case errno::ETIMEDOUT:
|
||||
return thread::WAIT_TIMEOUT?;
|
||||
return thread::WAIT_TIMEOUT~;
|
||||
case errno::OK:
|
||||
return;
|
||||
default:
|
||||
$if(env::OPENBSD):
|
||||
// TODO: Investigate why this doesn't work correctly on openbsd.
|
||||
return thread::WAIT_TIMEOUT?;
|
||||
return thread::WAIT_TIMEOUT~;
|
||||
$else
|
||||
abort("pthread_cond_timedwait failed, invalid value");
|
||||
$endif
|
||||
@@ -205,7 +205,7 @@ fn void? NativeThread.create(&thread, ThreadFn thread_fn, void* arg)
|
||||
thread.arg = arg;
|
||||
if (posix::pthread_create(&thread.pthread, null, &callback, thread) != 0)
|
||||
{
|
||||
return thread::INIT_FAILED?;
|
||||
return thread::INIT_FAILED~;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,6 +259,6 @@ fn void native_thread_yield()
|
||||
fn void? native_sleep_nano(NanoDuration nano)
|
||||
{
|
||||
if (nano <= time::NANO_DURATION_ZERO) return;
|
||||
if (libc::nanosleep(&&nano.to_timespec(), null)) return thread::INTERRUPTED?;
|
||||
if (libc::nanosleep(&&nano.to_timespec(), null)) return thread::INTERRUPTED~;
|
||||
}
|
||||
|
||||
|
||||
@@ -353,7 +353,7 @@ fn void? NativeConditionVariable.wait_until(&cond, NativeMutex* mtx, Time time)
|
||||
|
||||
fn void? NativeThread.create(&thread, ThreadFn func, void* args)
|
||||
{
|
||||
if (!(*thread = (NativeThread)win32::createThread(null, 0, func, args, 0, null))) return thread::INIT_FAILED?;
|
||||
if (!(*thread = (NativeThread)win32::createThread(null, 0, func, args, 0, null))) return thread::INIT_FAILED~;
|
||||
}
|
||||
|
||||
fn void NativeThread.detach(thread) @inline
|
||||
@@ -410,5 +410,5 @@ fn void? native_sleep_nano(NanoDuration ns)
|
||||
long ms = ns.to_ms();
|
||||
if (ms <= 0) return;
|
||||
if (ms > Win32_DWORD.max) ms = Win32_DWORD.max;
|
||||
if (win32::sleepEx((Win32_DWORD)ms, (Win32_BOOL)true) == win32::WAIT_IO_COMPLETION) return thread::INTERRUPTED?;
|
||||
if (win32::sleepEx((Win32_DWORD)ms, (Win32_BOOL)true) == win32::WAIT_IO_COMPLETION) return thread::INTERRUPTED~;
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ fn void? UnbufferedChannel.push(self, Type val)
|
||||
|
||||
if (channel.closed)
|
||||
{
|
||||
return thread::CHANNEL_CLOSED?;
|
||||
return thread::CHANNEL_CLOSED~;
|
||||
}
|
||||
|
||||
// store value in the buffer
|
||||
@@ -82,7 +82,7 @@ fn void? UnbufferedChannel.push(self, Type val)
|
||||
// wait until reader takes value from buffer
|
||||
channel.send_cond.wait(&channel.mu);
|
||||
|
||||
if (channel.closed) return thread::CHANNEL_CLOSED?;
|
||||
if (channel.closed) return thread::CHANNEL_CLOSED~;
|
||||
|
||||
channel.mu.unlock();
|
||||
channel.send_mu.unlock();
|
||||
@@ -105,7 +105,7 @@ fn Type? UnbufferedChannel.pop(self)
|
||||
channel.read_waiting--;
|
||||
}
|
||||
|
||||
if (channel.closed) return thread::CHANNEL_CLOSED?;
|
||||
if (channel.closed) return thread::CHANNEL_CLOSED~;
|
||||
|
||||
// take value from buffer
|
||||
Type ret = channel.buf;
|
||||
|
||||
Reference in New Issue
Block a user