mirror of
https://github.com/odin-lang/Odin.git
synced 2026-04-21 22:05:20 +00:00
gb_internal a lot
This commit is contained in:
144
src/array.cpp
144
src/array.cpp
@@ -23,32 +23,32 @@ struct Array {
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T> void array_init (Array<T> *array, gbAllocator const &a);
|
||||
template <typename T> void array_init (Array<T> *array, gbAllocator const &a, isize count);
|
||||
template <typename T> void array_init (Array<T> *array, gbAllocator const &a, isize count, isize capacity);
|
||||
template <typename T> Array<T> array_make (gbAllocator const &a);
|
||||
template <typename T> Array<T> array_make (gbAllocator const &a, isize count);
|
||||
template <typename T> Array<T> array_make (gbAllocator const &a, isize count, isize capacity);
|
||||
template <typename T> Array<T> array_make_from_ptr (T *data, isize count, isize capacity);
|
||||
template <typename T> void array_free (Array<T> *array);
|
||||
template <typename T> void array_add (Array<T> *array, T const &t);
|
||||
template <typename T> T * array_add_and_get (Array<T> *array);
|
||||
template <typename T> void array_add_elems (Array<T> *array, T const *elems, isize elem_count);
|
||||
template <typename T> T array_pop (Array<T> *array);
|
||||
template <typename T> void array_clear (Array<T> *array);
|
||||
template <typename T> void array_reserve (Array<T> *array, isize capacity);
|
||||
template <typename T> void array_resize (Array<T> *array, isize count);
|
||||
template <typename T> void array_set_capacity (Array<T> *array, isize capacity);
|
||||
template <typename T> Array<T> array_slice (Array<T> const &array, isize lo, isize hi);
|
||||
template <typename T> Array<T> array_clone (gbAllocator const &a, Array<T> const &array);
|
||||
template <typename T> gb_internal void array_init (Array<T> *array, gbAllocator const &a);
|
||||
template <typename T> gb_internal void array_init (Array<T> *array, gbAllocator const &a, isize count);
|
||||
template <typename T> gb_internal void array_init (Array<T> *array, gbAllocator const &a, isize count, isize capacity);
|
||||
template <typename T> gb_internal Array<T> array_make (gbAllocator const &a);
|
||||
template <typename T> gb_internal Array<T> array_make (gbAllocator const &a, isize count);
|
||||
template <typename T> gb_internal Array<T> array_make (gbAllocator const &a, isize count, isize capacity);
|
||||
template <typename T> gb_internal Array<T> array_make_from_ptr (T *data, isize count, isize capacity);
|
||||
template <typename T> gb_internal void array_free (Array<T> *array);
|
||||
template <typename T> gb_internal void array_add (Array<T> *array, T const &t);
|
||||
template <typename T> gb_internal T * array_add_and_get (Array<T> *array);
|
||||
template <typename T> gb_internal void array_add_elems (Array<T> *array, T const *elems, isize elem_count);
|
||||
template <typename T> gb_internal T array_pop (Array<T> *array);
|
||||
template <typename T> gb_internal void array_clear (Array<T> *array);
|
||||
template <typename T> gb_internal void array_reserve (Array<T> *array, isize capacity);
|
||||
template <typename T> gb_internal void array_resize (Array<T> *array, isize count);
|
||||
template <typename T> gb_internal void array_set_capacity (Array<T> *array, isize capacity);
|
||||
template <typename T> gb_internal Array<T> array_slice (Array<T> const &array, isize lo, isize hi);
|
||||
template <typename T> gb_internal Array<T> array_clone (gbAllocator const &a, Array<T> const &array);
|
||||
|
||||
template <typename T> void array_ordered_remove (Array<T> *array, isize index);
|
||||
template <typename T> void array_unordered_remove(Array<T> *array, isize index);
|
||||
template <typename T> gb_internal void array_ordered_remove (Array<T> *array, isize index);
|
||||
template <typename T> gb_internal void array_unordered_remove(Array<T> *array, isize index);
|
||||
|
||||
template <typename T> void array_copy(Array<T> *array, Array<T> const &data, isize offset);
|
||||
template <typename T> void array_copy(Array<T> *array, Array<T> const &data, isize offset, isize count);
|
||||
template <typename T> gb_internal void array_copy(Array<T> *array, Array<T> const &data, isize offset);
|
||||
template <typename T> gb_internal void array_copy(Array<T> *array, Array<T> const &data, isize offset, isize count);
|
||||
|
||||
template <typename T> T *array_end_ptr(Array<T> *array);
|
||||
template <typename T> gb_internal T *array_end_ptr(Array<T> *array);
|
||||
|
||||
|
||||
template <typename T>
|
||||
@@ -56,14 +56,14 @@ struct Slice {
|
||||
T *data;
|
||||
isize count;
|
||||
|
||||
T &operator[](isize index) {
|
||||
gb_inline T &operator[](isize index) {
|
||||
#if !defined(NO_ARRAY_BOUNDS_CHECK)
|
||||
GB_ASSERT_MSG(0 <= index && index < count, "Index %td is out of bounds ranges 0..<%td", index, count);
|
||||
#endif
|
||||
return data[index];
|
||||
}
|
||||
|
||||
T const &operator[](isize index) const {
|
||||
gb_inline T const &operator[](isize index) const {
|
||||
#if !defined(NO_ARRAY_BOUNDS_CHECK)
|
||||
GB_ASSERT_MSG(0 <= index && index < count, "Index %td is out of bounds ranges 0..<%td", index, count);
|
||||
#endif
|
||||
@@ -71,12 +71,12 @@ struct Slice {
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T> Slice<T> slice_from_array(Array<T> const &a);
|
||||
template <typename T> gb_internal Slice<T> slice_from_array(Array<T> const &a);
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
Slice<T> slice_make(gbAllocator const &allocator, isize count) {
|
||||
gb_internal Slice<T> slice_make(gbAllocator const &allocator, isize count) {
|
||||
GB_ASSERT(count >= 0);
|
||||
Slice<T> s = {};
|
||||
s.data = gb_alloc_array(allocator, T, count);
|
||||
@@ -86,7 +86,7 @@ Slice<T> slice_make(gbAllocator const &allocator, isize count) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void slice_init(Slice<T> *s, gbAllocator const &allocator, isize count) {
|
||||
gb_internal void slice_init(Slice<T> *s, gbAllocator const &allocator, isize count) {
|
||||
GB_ASSERT(count >= 0);
|
||||
s->data = gb_alloc_array(allocator, T, count);
|
||||
if (count > 0) {
|
||||
@@ -96,23 +96,23 @@ void slice_init(Slice<T> *s, gbAllocator const &allocator, isize count) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void slice_free(Slice<T> *s, gbAllocator const &allocator) {
|
||||
gb_internal void slice_free(Slice<T> *s, gbAllocator const &allocator) {
|
||||
gb_free(allocator, s->data);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void slice_resize(Slice<T> *s, gbAllocator const &allocator, isize new_count) {
|
||||
gb_internal void slice_resize(Slice<T> *s, gbAllocator const &allocator, isize new_count) {
|
||||
resize_array_raw(&s->data, allocator, s->count, new_count);
|
||||
s->count = new_count;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
Slice<T> slice_from_array(Array<T> const &a) {
|
||||
gb_internal Slice<T> slice_from_array(Array<T> const &a) {
|
||||
return {a.data, a.count};
|
||||
}
|
||||
template <typename T>
|
||||
Slice<T> slice_array(Array<T> const &array, isize lo, isize hi) {
|
||||
gb_internal Slice<T> slice_array(Array<T> const &array, isize lo, isize hi) {
|
||||
GB_ASSERT(0 <= lo && lo <= hi && hi <= array.count);
|
||||
Slice<T> out = {};
|
||||
isize len = hi-lo;
|
||||
@@ -125,30 +125,30 @@ Slice<T> slice_array(Array<T> const &array, isize lo, isize hi) {
|
||||
|
||||
|
||||
template <typename T>
|
||||
Slice<T> slice_clone(gbAllocator const &allocator, Slice<T> const &a) {
|
||||
gb_internal Slice<T> slice_clone(gbAllocator const &allocator, Slice<T> const &a) {
|
||||
T *data = cast(T *)gb_alloc_copy_align(allocator, a.data, a.count*gb_size_of(T), gb_align_of(T));
|
||||
return {data, a.count};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Slice<T> slice_clone_from_array(gbAllocator const &allocator, Array<T> const &a) {
|
||||
gb_internal Slice<T> slice_clone_from_array(gbAllocator const &allocator, Array<T> const &a) {
|
||||
auto c = array_clone(allocator, a);
|
||||
return {c.data, c.count};
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void slice_copy(Slice<T> *slice, Slice<T> const &data) {
|
||||
gb_internal void slice_copy(Slice<T> *slice, Slice<T> const &data) {
|
||||
isize n = gb_min(slice->count, data.count);
|
||||
gb_memmove(slice->data, data.data, gb_size_of(T)*n);
|
||||
}
|
||||
template <typename T>
|
||||
void slice_copy(Slice<T> *slice, Slice<T> const &data, isize offset) {
|
||||
gb_internal void slice_copy(Slice<T> *slice, Slice<T> const &data, isize offset) {
|
||||
isize n = gb_clamp(slice->count-offset, 0, data.count);
|
||||
gb_memmove(slice->data+offset, data.data, gb_size_of(T)*n);
|
||||
}
|
||||
template <typename T>
|
||||
void slice_copy(Slice<T> *slice, Slice<T> const &data, isize offset, isize count) {
|
||||
gb_internal void slice_copy(Slice<T> *slice, Slice<T> const &data, isize offset, isize count) {
|
||||
isize n = gb_clamp(slice->count-offset, 0, gb_min(data.count, count));
|
||||
gb_memmove(slice->data+offset, data.data, gb_size_of(T)*n);
|
||||
}
|
||||
@@ -156,7 +156,7 @@ void slice_copy(Slice<T> *slice, Slice<T> const &data, isize offset, isize count
|
||||
|
||||
|
||||
template <typename T>
|
||||
gb_inline Slice<T> slice(Slice<T> const &array, isize lo, isize hi) {
|
||||
gb_internal gb_inline Slice<T> slice(Slice<T> const &array, isize lo, isize hi) {
|
||||
GB_ASSERT(0 <= lo && lo <= hi && hi <= array.count);
|
||||
Slice<T> out = {};
|
||||
isize len = hi-lo;
|
||||
@@ -169,7 +169,7 @@ gb_inline Slice<T> slice(Slice<T> const &array, isize lo, isize hi) {
|
||||
|
||||
|
||||
template <typename T>
|
||||
void slice_ordered_remove(Slice<T> *array, isize index) {
|
||||
gb_internal void slice_ordered_remove(Slice<T> *array, isize index) {
|
||||
GB_ASSERT(0 <= index && index < array->count);
|
||||
|
||||
isize bytes = gb_size_of(T) * (array->count-(index+1));
|
||||
@@ -178,7 +178,7 @@ void slice_ordered_remove(Slice<T> *array, isize index) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void slice_unordered_remove(Slice<T> *array, isize index) {
|
||||
gb_internal void slice_unordered_remove(Slice<T> *array, isize index) {
|
||||
GB_ASSERT(0 <= index && index < array->count);
|
||||
|
||||
isize n = array->count-1;
|
||||
@@ -190,18 +190,18 @@ void slice_unordered_remove(Slice<T> *array, isize index) {
|
||||
|
||||
|
||||
template <typename T>
|
||||
void array_copy(Array<T> *array, Array<T> const &data, isize offset) {
|
||||
gb_internal void array_copy(Array<T> *array, Array<T> const &data, isize offset) {
|
||||
gb_memmove(array->data+offset, data.data, gb_size_of(T)*data.count);
|
||||
}
|
||||
template <typename T>
|
||||
void array_copy(Array<T> *array, Array<T> const &data, isize offset, isize count) {
|
||||
gb_internal void array_copy(Array<T> *array, Array<T> const &data, isize offset, isize count) {
|
||||
gb_memmove(array->data+offset, data.data, gb_size_of(T)*gb_min(data.count, count));
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
T *array_end_ptr(Array<T> *array) {
|
||||
gb_internal T *array_end_ptr(Array<T> *array) {
|
||||
if (array->count > 0) {
|
||||
return &array->data[array->count-1];
|
||||
}
|
||||
@@ -210,18 +210,18 @@ T *array_end_ptr(Array<T> *array) {
|
||||
|
||||
|
||||
template <typename T>
|
||||
gb_inline void array_init(Array<T> *array, gbAllocator const &a) {
|
||||
gb_internal gb_inline void array_init(Array<T> *array, gbAllocator const &a) {
|
||||
isize cap = ARRAY_GROW_FORMULA(0);
|
||||
array_init(array, a, 0, cap);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
gb_inline void array_init(Array<T> *array, gbAllocator const &a, isize count) {
|
||||
gb_internal gb_inline void array_init(Array<T> *array, gbAllocator const &a, isize count) {
|
||||
array_init(array, a, count, count);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
gb_inline void array_init(Array<T> *array, gbAllocator const &a, isize count, isize capacity) {
|
||||
gb_internal gb_inline void array_init(Array<T> *array, gbAllocator const &a, isize count, isize capacity) {
|
||||
array->allocator = a;
|
||||
array->data = nullptr;
|
||||
if (capacity > 0) {
|
||||
@@ -234,7 +234,7 @@ gb_inline void array_init(Array<T> *array, gbAllocator const &a, isize count, is
|
||||
|
||||
|
||||
template <typename T>
|
||||
gb_inline Array<T> array_make_from_ptr(T *data, isize count, isize capacity) {
|
||||
gb_internal gb_inline Array<T> array_make_from_ptr(T *data, isize count, isize capacity) {
|
||||
Array<T> a = {0};
|
||||
a.data = data;
|
||||
a.count = count;
|
||||
@@ -244,7 +244,7 @@ gb_inline Array<T> array_make_from_ptr(T *data, isize count, isize capacity) {
|
||||
|
||||
|
||||
template <typename T>
|
||||
gb_inline Array<T> array_make(gbAllocator const &a) {
|
||||
gb_internal gb_inline Array<T> array_make(gbAllocator const &a) {
|
||||
isize capacity = ARRAY_GROW_FORMULA(0);
|
||||
Array<T> array = {};
|
||||
array.allocator = a;
|
||||
@@ -254,7 +254,7 @@ gb_inline Array<T> array_make(gbAllocator const &a) {
|
||||
return array;
|
||||
}
|
||||
template <typename T>
|
||||
gb_inline Array<T> array_make(gbAllocator const &a, isize count) {
|
||||
gb_internal gb_inline Array<T> array_make(gbAllocator const &a, isize count) {
|
||||
Array<T> array = {};
|
||||
array.allocator = a;
|
||||
array.data = gb_alloc_array(a, T, count);
|
||||
@@ -263,7 +263,7 @@ gb_inline Array<T> array_make(gbAllocator const &a, isize count) {
|
||||
return array;
|
||||
}
|
||||
template <typename T>
|
||||
gb_inline Array<T> array_make(gbAllocator const &a, isize count, isize capacity) {
|
||||
gb_internal gb_inline Array<T> array_make(gbAllocator const &a, isize count, isize capacity) {
|
||||
Array<T> array = {};
|
||||
array.allocator = a;
|
||||
array.data = gb_alloc_array(a, T, capacity);
|
||||
@@ -275,7 +275,7 @@ gb_inline Array<T> array_make(gbAllocator const &a, isize count, isize capacity)
|
||||
|
||||
|
||||
template <typename T>
|
||||
gb_inline void array_free(Array<T> *array) {
|
||||
gb_internal gb_inline void array_free(Array<T> *array) {
|
||||
if (array->allocator.proc != nullptr) {
|
||||
gb_free(array->allocator, array->data);
|
||||
}
|
||||
@@ -284,7 +284,7 @@ gb_inline void array_free(Array<T> *array) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void array__grow(Array<T> *array, isize min_capacity) {
|
||||
gb_internal void array__grow(Array<T> *array, isize min_capacity) {
|
||||
isize new_capacity = ARRAY_GROW_FORMULA(array->capacity);
|
||||
if (new_capacity < min_capacity) {
|
||||
new_capacity = min_capacity;
|
||||
@@ -293,7 +293,7 @@ void array__grow(Array<T> *array, isize min_capacity) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void array_add(Array<T> *array, T const &t) {
|
||||
gb_internal void array_add(Array<T> *array, T const &t) {
|
||||
if (array->capacity < array->count+1) {
|
||||
array__grow(array, 0);
|
||||
}
|
||||
@@ -302,7 +302,7 @@ void array_add(Array<T> *array, T const &t) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T *array_add_and_get(Array<T> *array) {
|
||||
gb_internal T *array_add_and_get(Array<T> *array) {
|
||||
if (array->count < array->capacity) {
|
||||
return &array->data[array->count++];
|
||||
}
|
||||
@@ -314,7 +314,7 @@ T *array_add_and_get(Array<T> *array) {
|
||||
|
||||
|
||||
template <typename T>
|
||||
void array_add_elems(Array<T> *array, T const *elems, isize elem_count) {
|
||||
gb_internal void array_add_elems(Array<T> *array, T const *elems, isize elem_count) {
|
||||
GB_ASSERT(elem_count >= 0);
|
||||
if (array->capacity < array->count+elem_count) {
|
||||
array__grow(array, array->count+elem_count);
|
||||
@@ -325,26 +325,26 @@ void array_add_elems(Array<T> *array, T const *elems, isize elem_count) {
|
||||
|
||||
|
||||
template <typename T>
|
||||
gb_inline T array_pop(Array<T> *array) {
|
||||
gb_internal gb_inline T array_pop(Array<T> *array) {
|
||||
GB_ASSERT(array->count > 0);
|
||||
array->count--;
|
||||
return array->data[array->count];
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void array_clear(Array<T> *array) {
|
||||
gb_internal void array_clear(Array<T> *array) {
|
||||
array->count = 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void array_reserve(Array<T> *array, isize capacity) {
|
||||
gb_internal void array_reserve(Array<T> *array, isize capacity) {
|
||||
if (array->capacity < capacity) {
|
||||
array_set_capacity(array, capacity);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void array_resize(Array<T> *array, isize count) {
|
||||
gb_internal void array_resize(Array<T> *array, isize count) {
|
||||
if (array->capacity < count) {
|
||||
array__grow(array, count);
|
||||
}
|
||||
@@ -352,7 +352,7 @@ void array_resize(Array<T> *array, isize count) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void array_set_capacity(Array<T> *array, isize capacity) {
|
||||
gb_internal void array_set_capacity(Array<T> *array, isize capacity) {
|
||||
if (capacity == array->capacity) {
|
||||
return;
|
||||
}
|
||||
@@ -381,7 +381,7 @@ void array_set_capacity(Array<T> *array, isize capacity) {
|
||||
|
||||
|
||||
template <typename T>
|
||||
gb_inline Array<T> array_slice(Array<T> const &array, isize lo, isize hi) {
|
||||
gb_internal gb_inline Array<T> array_slice(Array<T> const &array, isize lo, isize hi) {
|
||||
GB_ASSERT(0 <= lo && lo <= hi && hi <= array.count);
|
||||
Array<T> out = {};
|
||||
isize len = hi-lo;
|
||||
@@ -394,7 +394,7 @@ gb_inline Array<T> array_slice(Array<T> const &array, isize lo, isize hi) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Array<T> array_clone(gbAllocator const &allocator, Array<T> const &array) {
|
||||
gb_internal Array<T> array_clone(gbAllocator const &allocator, Array<T> const &array) {
|
||||
auto clone = array_make<T>(allocator, array.count, array.count);
|
||||
array_copy(&clone, array, 0);
|
||||
return clone;
|
||||
@@ -402,7 +402,7 @@ Array<T> array_clone(gbAllocator const &allocator, Array<T> const &array) {
|
||||
|
||||
|
||||
template <typename T>
|
||||
void array_ordered_remove(Array<T> *array, isize index) {
|
||||
gb_internal void array_ordered_remove(Array<T> *array, isize index) {
|
||||
GB_ASSERT(0 <= index && index < array->count);
|
||||
|
||||
isize bytes = gb_size_of(T) * (array->count-(index+1));
|
||||
@@ -411,7 +411,7 @@ void array_ordered_remove(Array<T> *array, isize index) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void array_unordered_remove(Array<T> *array, isize index) {
|
||||
gb_internal void array_unordered_remove(Array<T> *array, isize index) {
|
||||
GB_ASSERT(0 <= index && index < array->count);
|
||||
|
||||
isize n = array->count-1;
|
||||
@@ -424,35 +424,35 @@ void array_unordered_remove(Array<T> *array, isize index) {
|
||||
|
||||
|
||||
template <typename T>
|
||||
T *begin(Array<T> &array) {
|
||||
gb_internal T *begin(Array<T> &array) {
|
||||
return array.data;
|
||||
}
|
||||
template <typename T>
|
||||
T const *begin(Array<T> const &array) {
|
||||
gb_internal T const *begin(Array<T> const &array) {
|
||||
return array.data;
|
||||
}
|
||||
template <typename T>
|
||||
T *end(Array<T> &array) {
|
||||
gb_internal T *end(Array<T> &array) {
|
||||
return array.data + array.count;
|
||||
}
|
||||
template <typename T>
|
||||
T const *end(Array<T> const &array) {
|
||||
gb_internal T const *end(Array<T> const &array) {
|
||||
return array.data + array.count;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T *begin(Slice<T> &array) {
|
||||
gb_internal T *begin(Slice<T> &array) {
|
||||
return array.data;
|
||||
}
|
||||
template <typename T>
|
||||
T const *begin(Slice<T> const &array) {
|
||||
gb_internal T const *begin(Slice<T> const &array) {
|
||||
return array.data;
|
||||
}
|
||||
template <typename T>
|
||||
T *end(Slice<T> &array) {
|
||||
gb_internal T *end(Slice<T> &array) {
|
||||
return array.data + array.count;
|
||||
}
|
||||
template <typename T>
|
||||
T const *end(Slice<T> const &array) {
|
||||
gb_internal T const *end(Slice<T> const &array) {
|
||||
return array.data + array.count;
|
||||
}
|
||||
|
||||
158
src/big_int.cpp
158
src/big_int.cpp
@@ -37,86 +37,86 @@ void MP_FREE(void *mem, size_t size) {
|
||||
|
||||
typedef mp_int BigInt;
|
||||
|
||||
void big_int_from_u64(BigInt *dst, u64 x);
|
||||
void big_int_from_i64(BigInt *dst, i64 x);
|
||||
void big_int_init (BigInt *dst, BigInt const *src);
|
||||
void big_int_from_string(BigInt *dst, String const &s, bool *success);
|
||||
gb_internal void big_int_from_u64(BigInt *dst, u64 x);
|
||||
gb_internal void big_int_from_i64(BigInt *dst, i64 x);
|
||||
gb_internal void big_int_init (BigInt *dst, BigInt const *src);
|
||||
gb_internal void big_int_from_string(BigInt *dst, String const &s, bool *success);
|
||||
|
||||
void big_int_dealloc(BigInt *dst) {
|
||||
gb_internal void big_int_dealloc(BigInt *dst) {
|
||||
mp_clear(dst);
|
||||
}
|
||||
|
||||
BigInt big_int_make(BigInt const *b, bool abs=false);
|
||||
BigInt big_int_make_abs(BigInt const *b);
|
||||
BigInt big_int_make_u64(u64 x);
|
||||
BigInt big_int_make_i64(i64 x);
|
||||
gb_internal BigInt big_int_make(BigInt const *b, bool abs=false);
|
||||
gb_internal BigInt big_int_make_abs(BigInt const *b);
|
||||
gb_internal BigInt big_int_make_u64(u64 x);
|
||||
gb_internal BigInt big_int_make_i64(i64 x);
|
||||
|
||||
u64 big_int_to_u64 (BigInt const *x);
|
||||
i64 big_int_to_i64 (BigInt const *x);
|
||||
f64 big_int_to_f64 (BigInt const *x);
|
||||
String big_int_to_string(gbAllocator allocator, BigInt const *x, u64 base = 10);
|
||||
gb_internal u64 big_int_to_u64 (BigInt const *x);
|
||||
gb_internal i64 big_int_to_i64 (BigInt const *x);
|
||||
gb_internal f64 big_int_to_f64 (BigInt const *x);
|
||||
gb_internal String big_int_to_string(gbAllocator allocator, BigInt const *x, u64 base = 10);
|
||||
|
||||
void big_int_add (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
void big_int_sub (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
void big_int_shl (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
void big_int_shr (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
void big_int_mul (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
void big_int_mul_u64(BigInt *dst, BigInt const *x, u64 y);
|
||||
gb_internal void big_int_add (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
gb_internal void big_int_sub (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
gb_internal void big_int_shl (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
gb_internal void big_int_shr (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
gb_internal void big_int_mul (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
gb_internal void big_int_mul_u64(BigInt *dst, BigInt const *x, u64 y);
|
||||
|
||||
void big_int_quo_rem(BigInt const *x, BigInt const *y, BigInt *q, BigInt *r);
|
||||
void big_int_quo (BigInt *z, BigInt const *x, BigInt const *y);
|
||||
void big_int_rem (BigInt *z, BigInt const *x, BigInt const *y);
|
||||
gb_internal void big_int_quo_rem(BigInt const *x, BigInt const *y, BigInt *q, BigInt *r);
|
||||
gb_internal void big_int_quo (BigInt *z, BigInt const *x, BigInt const *y);
|
||||
gb_internal void big_int_rem (BigInt *z, BigInt const *x, BigInt const *y);
|
||||
|
||||
void big_int_and (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
void big_int_and_not(BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
void big_int_xor (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
void big_int_or (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
void big_int_not (BigInt *dst, BigInt const *x, i32 bit_count, bool is_signed);
|
||||
gb_internal void big_int_and (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
gb_internal void big_int_and_not(BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
gb_internal void big_int_xor (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
gb_internal void big_int_or (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
gb_internal void big_int_not (BigInt *dst, BigInt const *x, i32 bit_count, bool is_signed);
|
||||
|
||||
|
||||
void big_int_add_eq(BigInt *dst, BigInt const *x);
|
||||
void big_int_sub_eq(BigInt *dst, BigInt const *x);
|
||||
void big_int_shl_eq(BigInt *dst, BigInt const *x);
|
||||
void big_int_shr_eq(BigInt *dst, BigInt const *x);
|
||||
void big_int_mul_eq(BigInt *dst, BigInt const *x);
|
||||
gb_internal void big_int_add_eq(BigInt *dst, BigInt const *x);
|
||||
gb_internal void big_int_sub_eq(BigInt *dst, BigInt const *x);
|
||||
gb_internal void big_int_shl_eq(BigInt *dst, BigInt const *x);
|
||||
gb_internal void big_int_shr_eq(BigInt *dst, BigInt const *x);
|
||||
gb_internal void big_int_mul_eq(BigInt *dst, BigInt const *x);
|
||||
|
||||
void big_int_quo_eq(BigInt *dst, BigInt const *x);
|
||||
void big_int_rem_eq(BigInt *dst, BigInt const *x);
|
||||
gb_internal void big_int_quo_eq(BigInt *dst, BigInt const *x);
|
||||
gb_internal void big_int_rem_eq(BigInt *dst, BigInt const *x);
|
||||
|
||||
bool big_int_is_neg(BigInt const *x);
|
||||
void big_int_neg(BigInt *dst, BigInt const *x);
|
||||
gb_internal bool big_int_is_neg(BigInt const *x);
|
||||
gb_internal void big_int_neg(BigInt *dst, BigInt const *x);
|
||||
|
||||
void big_int_add_eq(BigInt *dst, BigInt const *x) {
|
||||
gb_internal void big_int_add_eq(BigInt *dst, BigInt const *x) {
|
||||
BigInt res = {};
|
||||
big_int_init(&res, dst);
|
||||
big_int_add(dst, &res, x);
|
||||
}
|
||||
void big_int_sub_eq(BigInt *dst, BigInt const *x) {
|
||||
gb_internal void big_int_sub_eq(BigInt *dst, BigInt const *x) {
|
||||
BigInt res = {};
|
||||
big_int_init(&res, dst);
|
||||
big_int_sub(dst, &res, x);
|
||||
}
|
||||
void big_int_shl_eq(BigInt *dst, BigInt const *x) {
|
||||
gb_internal void big_int_shl_eq(BigInt *dst, BigInt const *x) {
|
||||
BigInt res = {};
|
||||
big_int_init(&res, dst);
|
||||
big_int_shl(dst, &res, x);
|
||||
}
|
||||
void big_int_shr_eq(BigInt *dst, BigInt const *x) {
|
||||
gb_internal void big_int_shr_eq(BigInt *dst, BigInt const *x) {
|
||||
BigInt res = {};
|
||||
big_int_init(&res, dst);
|
||||
big_int_shr(dst, &res, x);
|
||||
}
|
||||
void big_int_mul_eq(BigInt *dst, BigInt const *x) {
|
||||
gb_internal void big_int_mul_eq(BigInt *dst, BigInt const *x) {
|
||||
BigInt res = {};
|
||||
big_int_init(&res, dst);
|
||||
big_int_mul(dst, &res, x);
|
||||
}
|
||||
void big_int_quo_eq(BigInt *dst, BigInt const *x) {
|
||||
gb_internal void big_int_quo_eq(BigInt *dst, BigInt const *x) {
|
||||
BigInt res = {};
|
||||
big_int_init(&res, dst);
|
||||
big_int_quo(dst, &res, x);
|
||||
}
|
||||
void big_int_rem_eq(BigInt *dst, BigInt const *x) {
|
||||
gb_internal void big_int_rem_eq(BigInt *dst, BigInt const *x) {
|
||||
BigInt res = {};
|
||||
big_int_init(&res, dst);
|
||||
big_int_rem(dst, &res, x);
|
||||
@@ -124,7 +124,7 @@ void big_int_rem_eq(BigInt *dst, BigInt const *x) {
|
||||
|
||||
|
||||
|
||||
i64 big_int_sign(BigInt const *x) {
|
||||
gb_internal i64 big_int_sign(BigInt const *x) {
|
||||
if (mp_iszero(x)) {
|
||||
return 0;
|
||||
}
|
||||
@@ -132,44 +132,44 @@ i64 big_int_sign(BigInt const *x) {
|
||||
}
|
||||
|
||||
|
||||
void big_int_from_u64(BigInt *dst, u64 x) {
|
||||
gb_internal void big_int_from_u64(BigInt *dst, u64 x) {
|
||||
mp_init_u64(dst, x);
|
||||
}
|
||||
void big_int_from_i64(BigInt *dst, i64 x) {
|
||||
gb_internal void big_int_from_i64(BigInt *dst, i64 x) {
|
||||
mp_init_i64(dst, x);
|
||||
|
||||
}
|
||||
void big_int_init(BigInt *dst, BigInt const *src) {
|
||||
gb_internal void big_int_init(BigInt *dst, BigInt const *src) {
|
||||
if (dst == src) {
|
||||
return;
|
||||
}
|
||||
mp_init_copy(dst, src);
|
||||
}
|
||||
|
||||
BigInt big_int_make(BigInt const *b, bool abs) {
|
||||
gb_internal BigInt big_int_make(BigInt const *b, bool abs) {
|
||||
BigInt i = {};
|
||||
big_int_init(&i, b);
|
||||
if (abs) mp_abs(&i, &i);
|
||||
return i;
|
||||
}
|
||||
BigInt big_int_make_abs(BigInt const *b) {
|
||||
gb_internal BigInt big_int_make_abs(BigInt const *b) {
|
||||
return big_int_make(b, true);
|
||||
}
|
||||
|
||||
|
||||
BigInt big_int_make_u64(u64 x) {
|
||||
gb_internal BigInt big_int_make_u64(u64 x) {
|
||||
BigInt i = {};
|
||||
big_int_from_u64(&i, x);
|
||||
return i;
|
||||
}
|
||||
BigInt big_int_make_i64(i64 x) {
|
||||
gb_internal BigInt big_int_make_i64(i64 x) {
|
||||
BigInt i = {};
|
||||
big_int_from_i64(&i, x);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
void big_int_from_string(BigInt *dst, String const &s, bool *success) {
|
||||
gb_internal void big_int_from_string(BigInt *dst, String const &s, bool *success) {
|
||||
*success = true;
|
||||
|
||||
bool is_negative = false;
|
||||
@@ -262,66 +262,66 @@ void big_int_from_string(BigInt *dst, String const &s, bool *success) {
|
||||
|
||||
|
||||
|
||||
u64 big_int_to_u64(BigInt const *x) {
|
||||
gb_internal u64 big_int_to_u64(BigInt const *x) {
|
||||
GB_ASSERT(x->sign == 0);
|
||||
return mp_get_u64(x);
|
||||
}
|
||||
|
||||
i64 big_int_to_i64(BigInt const *x) {
|
||||
gb_internal i64 big_int_to_i64(BigInt const *x) {
|
||||
return mp_get_i64(x);
|
||||
}
|
||||
|
||||
f64 big_int_to_f64(BigInt const *x) {
|
||||
gb_internal f64 big_int_to_f64(BigInt const *x) {
|
||||
return mp_get_double(x);
|
||||
}
|
||||
|
||||
|
||||
void big_int_neg(BigInt *dst, BigInt const *x) {
|
||||
gb_internal void big_int_neg(BigInt *dst, BigInt const *x) {
|
||||
mp_neg(x, dst);
|
||||
}
|
||||
|
||||
|
||||
int big_int_cmp(BigInt const *x, BigInt const *y) {
|
||||
gb_internal int big_int_cmp(BigInt const *x, BigInt const *y) {
|
||||
return mp_cmp(x, y);
|
||||
}
|
||||
|
||||
int big_int_cmp_zero(BigInt const *x) {
|
||||
gb_internal int big_int_cmp_zero(BigInt const *x) {
|
||||
if (mp_iszero(x)) {
|
||||
return 0;
|
||||
}
|
||||
return x->sign ? -1 : +1;
|
||||
}
|
||||
|
||||
bool big_int_is_zero(BigInt const *x) {
|
||||
gb_internal bool big_int_is_zero(BigInt const *x) {
|
||||
return mp_iszero(x);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void big_int_add(BigInt *dst, BigInt const *x, BigInt const *y) {
|
||||
gb_internal void big_int_add(BigInt *dst, BigInt const *x, BigInt const *y) {
|
||||
mp_add(x, y, dst);
|
||||
}
|
||||
|
||||
|
||||
void big_int_sub(BigInt *dst, BigInt const *x, BigInt const *y) {
|
||||
gb_internal void big_int_sub(BigInt *dst, BigInt const *x, BigInt const *y) {
|
||||
mp_sub(x, y, dst);
|
||||
}
|
||||
|
||||
|
||||
void big_int_shl(BigInt *dst, BigInt const *x, BigInt const *y) {
|
||||
gb_internal void big_int_shl(BigInt *dst, BigInt const *x, BigInt const *y) {
|
||||
u32 yy = mp_get_u32(y);
|
||||
mp_mul_2d(x, yy, dst);
|
||||
}
|
||||
|
||||
void big_int_shr(BigInt *dst, BigInt const *x, BigInt const *y) {
|
||||
gb_internal void big_int_shr(BigInt *dst, BigInt const *x, BigInt const *y) {
|
||||
u32 yy = mp_get_u32(y);
|
||||
BigInt d = {};
|
||||
mp_div_2d(x, yy, dst, &d);
|
||||
big_int_dealloc(&d);
|
||||
}
|
||||
|
||||
void big_int_mul_u64(BigInt *dst, BigInt const *x, u64 y) {
|
||||
gb_internal void big_int_mul_u64(BigInt *dst, BigInt const *x, u64 y) {
|
||||
BigInt d = {};
|
||||
big_int_from_u64(&d, y);
|
||||
mp_mul(x, &d, dst);
|
||||
@@ -329,12 +329,12 @@ void big_int_mul_u64(BigInt *dst, BigInt const *x, u64 y) {
|
||||
}
|
||||
|
||||
|
||||
void big_int_mul(BigInt *dst, BigInt const *x, BigInt const *y) {
|
||||
gb_internal void big_int_mul(BigInt *dst, BigInt const *x, BigInt const *y) {
|
||||
mp_mul(x, y, dst);
|
||||
}
|
||||
|
||||
|
||||
u64 leading_zeros_u64(u64 x) {
|
||||
gb_internal u64 leading_zeros_u64(u64 x) {
|
||||
#if defined(GB_COMPILER_MSVC)
|
||||
#if defined(GB_ARCH_64_BIT)
|
||||
return __lzcnt64(x);
|
||||
@@ -367,23 +367,23 @@ u64 leading_zeros_u64(u64 x) {
|
||||
//
|
||||
// q = x/y with the result truncated to zero
|
||||
// r = x - y*q
|
||||
void big_int_quo_rem(BigInt const *x, BigInt const *y, BigInt *q_, BigInt *r_) {
|
||||
gb_internal void big_int_quo_rem(BigInt const *x, BigInt const *y, BigInt *q_, BigInt *r_) {
|
||||
mp_div(x, y, q_, r_);
|
||||
}
|
||||
|
||||
void big_int_quo(BigInt *z, BigInt const *x, BigInt const *y) {
|
||||
gb_internal void big_int_quo(BigInt *z, BigInt const *x, BigInt const *y) {
|
||||
BigInt r = {};
|
||||
big_int_quo_rem(x, y, z, &r);
|
||||
big_int_dealloc(&r);
|
||||
}
|
||||
|
||||
void big_int_rem(BigInt *z, BigInt const *x, BigInt const *y) {
|
||||
gb_internal void big_int_rem(BigInt *z, BigInt const *x, BigInt const *y) {
|
||||
BigInt q = {};
|
||||
big_int_quo_rem(x, y, &q, z);
|
||||
big_int_dealloc(&q);
|
||||
}
|
||||
|
||||
void big_int_euclidean_mod(BigInt *z, BigInt const *x, BigInt const *y) {
|
||||
gb_internal void big_int_euclidean_mod(BigInt *z, BigInt const *x, BigInt const *y) {
|
||||
BigInt y0 = {};
|
||||
big_int_init(&y0, y);
|
||||
|
||||
@@ -400,11 +400,11 @@ void big_int_euclidean_mod(BigInt *z, BigInt const *x, BigInt const *y) {
|
||||
|
||||
|
||||
|
||||
void big_int_and(BigInt *dst, BigInt const *x, BigInt const *y) {
|
||||
gb_internal void big_int_and(BigInt *dst, BigInt const *x, BigInt const *y) {
|
||||
mp_and(x, y, dst);
|
||||
}
|
||||
|
||||
void big_int_and_not(BigInt *dst, BigInt const *x, BigInt const *y) {
|
||||
gb_internal void big_int_and_not(BigInt *dst, BigInt const *x, BigInt const *y) {
|
||||
if (mp_iszero(x)) {
|
||||
big_int_init(dst, y);
|
||||
return;
|
||||
@@ -467,22 +467,22 @@ void big_int_and_not(BigInt *dst, BigInt const *x, BigInt const *y) {
|
||||
return;
|
||||
}
|
||||
|
||||
void big_int_xor(BigInt *dst, BigInt const *x, BigInt const *y) {
|
||||
gb_internal void big_int_xor(BigInt *dst, BigInt const *x, BigInt const *y) {
|
||||
mp_xor(x, y, dst);
|
||||
}
|
||||
|
||||
|
||||
void big_int_or(BigInt *dst, BigInt const *x, BigInt const *y) {
|
||||
gb_internal void big_int_or(BigInt *dst, BigInt const *x, BigInt const *y) {
|
||||
mp_or(x, y, dst);
|
||||
}
|
||||
|
||||
void debug_print_big_int(BigInt const *x) {
|
||||
gb_internal void debug_print_big_int(BigInt const *x) {
|
||||
String s = big_int_to_string(temporary_allocator(), x, 10);
|
||||
gb_printf_err("[DEBUG] %.*s\n", LIT(s));
|
||||
}
|
||||
|
||||
|
||||
void big_int_not(BigInt *dst, BigInt const *x, i32 bit_count, bool is_signed) {
|
||||
gb_internal void big_int_not(BigInt *dst, BigInt const *x, i32 bit_count, bool is_signed) {
|
||||
GB_ASSERT(bit_count >= 0);
|
||||
if (bit_count == 0) {
|
||||
big_int_from_u64(dst, 0);
|
||||
@@ -530,7 +530,7 @@ void big_int_not(BigInt *dst, BigInt const *x, i32 bit_count, bool is_signed) {
|
||||
big_int_dealloc(&v);
|
||||
}
|
||||
|
||||
bool big_int_is_neg(BigInt const *x) {
|
||||
gb_internal bool big_int_is_neg(BigInt const *x) {
|
||||
if (x == nullptr) {
|
||||
return false;
|
||||
}
|
||||
@@ -538,7 +538,7 @@ bool big_int_is_neg(BigInt const *x) {
|
||||
}
|
||||
|
||||
|
||||
char digit_to_char(u8 digit) {
|
||||
gb_internal char digit_to_char(u8 digit) {
|
||||
GB_ASSERT(digit < 16);
|
||||
if (digit <= 9) {
|
||||
return digit + '0';
|
||||
@@ -548,7 +548,7 @@ char digit_to_char(u8 digit) {
|
||||
return '0';
|
||||
}
|
||||
|
||||
String big_int_to_string(gbAllocator allocator, BigInt const *x, u64 base) {
|
||||
gb_internal String big_int_to_string(gbAllocator allocator, BigInt const *x, u64 base) {
|
||||
GB_ASSERT(base <= 16);
|
||||
|
||||
if (mp_iszero(x)) {
|
||||
|
||||
@@ -57,7 +57,7 @@ enum TargetABIKind : u16 {
|
||||
};
|
||||
|
||||
|
||||
String target_os_names[TargetOs_COUNT] = {
|
||||
gb_global String target_os_names[TargetOs_COUNT] = {
|
||||
str_lit(""),
|
||||
str_lit("windows"),
|
||||
str_lit("darwin"),
|
||||
@@ -72,7 +72,7 @@ String target_os_names[TargetOs_COUNT] = {
|
||||
str_lit("freestanding"),
|
||||
};
|
||||
|
||||
String target_arch_names[TargetArch_COUNT] = {
|
||||
gb_global String target_arch_names[TargetArch_COUNT] = {
|
||||
str_lit(""),
|
||||
str_lit("amd64"),
|
||||
str_lit("i386"),
|
||||
@@ -82,19 +82,19 @@ String target_arch_names[TargetArch_COUNT] = {
|
||||
str_lit("wasm64"),
|
||||
};
|
||||
|
||||
String target_endian_names[TargetEndian_COUNT] = {
|
||||
gb_global String target_endian_names[TargetEndian_COUNT] = {
|
||||
str_lit(""),
|
||||
str_lit("little"),
|
||||
str_lit("big"),
|
||||
};
|
||||
|
||||
String target_abi_names[TargetABI_COUNT] = {
|
||||
gb_global String target_abi_names[TargetABI_COUNT] = {
|
||||
str_lit(""),
|
||||
str_lit("win64"),
|
||||
str_lit("sysv"),
|
||||
};
|
||||
|
||||
TargetEndianKind target_endians[TargetArch_COUNT] = {
|
||||
gb_global TargetEndianKind target_endians[TargetArch_COUNT] = {
|
||||
TargetEndian_Invalid,
|
||||
TargetEndian_Little,
|
||||
TargetEndian_Little,
|
||||
@@ -107,7 +107,7 @@ TargetEndianKind target_endians[TargetArch_COUNT] = {
|
||||
#define ODIN_VERSION_RAW "dev-unknown-unknown"
|
||||
#endif
|
||||
|
||||
String const ODIN_VERSION = str_lit(ODIN_VERSION_RAW);
|
||||
gb_global String const ODIN_VERSION = str_lit(ODIN_VERSION_RAW);
|
||||
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ enum CommandKind : u32 {
|
||||
Command_all = ~(u32)0,
|
||||
};
|
||||
|
||||
char const *odin_command_strings[32] = {
|
||||
gb_global char const *odin_command_strings[32] = {
|
||||
"run",
|
||||
"build",
|
||||
"check",
|
||||
@@ -333,10 +333,10 @@ struct BuildContext {
|
||||
|
||||
gb_global BuildContext build_context = {0};
|
||||
|
||||
bool global_warnings_as_errors(void) {
|
||||
gb_internal bool global_warnings_as_errors(void) {
|
||||
return build_context.warnings_as_errors;
|
||||
}
|
||||
bool global_ignore_warnings(void) {
|
||||
gb_internal bool global_ignore_warnings(void) {
|
||||
return build_context.ignore_warnings;
|
||||
}
|
||||
|
||||
@@ -502,9 +502,9 @@ gb_global NamedTargetMetrics named_targets[] = {
|
||||
{ str_lit("freestanding_amd64_sysv"), &target_freestanding_amd64_sysv },
|
||||
};
|
||||
|
||||
NamedTargetMetrics *selected_target_metrics;
|
||||
gb_global NamedTargetMetrics *selected_target_metrics;
|
||||
|
||||
TargetOsKind get_target_os_from_string(String str) {
|
||||
gb_internal TargetOsKind get_target_os_from_string(String str) {
|
||||
for (isize i = 0; i < TargetOs_COUNT; i++) {
|
||||
if (str_eq_ignore_case(target_os_names[i], str)) {
|
||||
return cast(TargetOsKind)i;
|
||||
@@ -513,7 +513,7 @@ TargetOsKind get_target_os_from_string(String str) {
|
||||
return TargetOs_Invalid;
|
||||
}
|
||||
|
||||
TargetArchKind get_target_arch_from_string(String str) {
|
||||
gb_internal TargetArchKind get_target_arch_from_string(String str) {
|
||||
for (isize i = 0; i < TargetArch_COUNT; i++) {
|
||||
if (str_eq_ignore_case(target_arch_names[i], str)) {
|
||||
return cast(TargetArchKind)i;
|
||||
@@ -523,7 +523,7 @@ TargetArchKind get_target_arch_from_string(String str) {
|
||||
}
|
||||
|
||||
|
||||
bool is_excluded_target_filename(String name) {
|
||||
gb_internal bool is_excluded_target_filename(String name) {
|
||||
String original_name = name;
|
||||
name = remove_extension_from_path(name);
|
||||
|
||||
@@ -588,13 +588,13 @@ struct LibraryCollections {
|
||||
|
||||
gb_global Array<LibraryCollections> library_collections = {0};
|
||||
|
||||
void add_library_collection(String name, String path) {
|
||||
gb_internal void add_library_collection(String name, String path) {
|
||||
// TODO(bill): Check the path is valid and a directory
|
||||
LibraryCollections lc = {name, string_trim_whitespace(path)};
|
||||
array_add(&library_collections, lc);
|
||||
}
|
||||
|
||||
bool find_library_collection_path(String name, String *path) {
|
||||
gb_internal bool find_library_collection_path(String name, String *path) {
|
||||
for_array(i, library_collections) {
|
||||
if (library_collections[i].name == name) {
|
||||
if (path) *path = library_collections[i].path;
|
||||
@@ -604,7 +604,7 @@ bool find_library_collection_path(String name, String *path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_arch_wasm(void) {
|
||||
gb_internal bool is_arch_wasm(void) {
|
||||
switch (build_context.metrics.arch) {
|
||||
case TargetArch_wasm32:
|
||||
case TargetArch_wasm64:
|
||||
@@ -613,7 +613,7 @@ bool is_arch_wasm(void) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_arch_x86(void) {
|
||||
gb_internal bool is_arch_x86(void) {
|
||||
switch (build_context.metrics.arch) {
|
||||
case TargetArch_i386:
|
||||
case TargetArch_amd64:
|
||||
@@ -622,7 +622,7 @@ bool is_arch_x86(void) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool allow_check_foreign_filepath(void) {
|
||||
gb_internal bool allow_check_foreign_filepath(void) {
|
||||
switch (build_context.metrics.arch) {
|
||||
case TargetArch_wasm32:
|
||||
case TargetArch_wasm64:
|
||||
@@ -638,13 +638,14 @@ bool allow_check_foreign_filepath(void) {
|
||||
// is_abs_path
|
||||
// has_subdir
|
||||
|
||||
String const WIN32_SEPARATOR_STRING = {cast(u8 *)"\\", 1};
|
||||
String const NIX_SEPARATOR_STRING = {cast(u8 *)"/", 1};
|
||||
gb_global String const WIN32_SEPARATOR_STRING = {cast(u8 *)"\\", 1};
|
||||
gb_global String const NIX_SEPARATOR_STRING = {cast(u8 *)"/", 1};
|
||||
|
||||
String const WASM_MODULE_NAME_SEPARATOR = str_lit("..");
|
||||
gb_global String const WASM_MODULE_NAME_SEPARATOR = str_lit("..");
|
||||
|
||||
String internal_odin_root_dir(void);
|
||||
String odin_root_dir(void) {
|
||||
gb_internal String internal_odin_root_dir(void);
|
||||
|
||||
gb_internal String odin_root_dir(void) {
|
||||
if (global_module_path_set) {
|
||||
return global_module_path;
|
||||
}
|
||||
@@ -670,7 +671,7 @@ String odin_root_dir(void) {
|
||||
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
String internal_odin_root_dir(void) {
|
||||
gb_internal String internal_odin_root_dir(void) {
|
||||
String path = global_module_path;
|
||||
isize len, i;
|
||||
wchar_t *text;
|
||||
@@ -725,7 +726,7 @@ String internal_odin_root_dir(void) {
|
||||
|
||||
String path_to_fullpath(gbAllocator a, String s);
|
||||
|
||||
String internal_odin_root_dir(void) {
|
||||
gb_internal String internal_odin_root_dir(void) {
|
||||
String path = global_module_path;
|
||||
isize len, i;
|
||||
u8 *text;
|
||||
@@ -777,9 +778,9 @@ String internal_odin_root_dir(void) {
|
||||
// NOTE: Linux / Unix is unfinished and not tested very well.
|
||||
#include <sys/stat.h>
|
||||
|
||||
String path_to_fullpath(gbAllocator a, String s);
|
||||
gb_internal String path_to_fullpath(gbAllocator a, String s);
|
||||
|
||||
String internal_odin_root_dir(void) {
|
||||
gb_internal String internal_odin_root_dir(void) {
|
||||
String path = global_module_path;
|
||||
isize len, i;
|
||||
u8 *text;
|
||||
@@ -938,7 +939,7 @@ String internal_odin_root_dir(void) {
|
||||
gb_global BlockingMutex fullpath_mutex;
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
String path_to_fullpath(gbAllocator a, String s) {
|
||||
gb_internal String path_to_fullpath(gbAllocator a, String s) {
|
||||
String result = {};
|
||||
mutex_lock(&fullpath_mutex);
|
||||
defer (mutex_unlock(&fullpath_mutex));
|
||||
@@ -965,7 +966,7 @@ String path_to_fullpath(gbAllocator a, String s) {
|
||||
return result;
|
||||
}
|
||||
#elif defined(GB_SYSTEM_OSX) || defined(GB_SYSTEM_UNIX)
|
||||
String path_to_fullpath(gbAllocator a, String s) {
|
||||
gb_internal String path_to_fullpath(gbAllocator a, String s) {
|
||||
char *p;
|
||||
mutex_lock(&fullpath_mutex);
|
||||
p = realpath(cast(char *)s.text, 0);
|
||||
@@ -978,7 +979,7 @@ String path_to_fullpath(gbAllocator a, String s) {
|
||||
#endif
|
||||
|
||||
|
||||
String get_fullpath_relative(gbAllocator a, String base_dir, String path) {
|
||||
gb_internal String get_fullpath_relative(gbAllocator a, String base_dir, String path) {
|
||||
u8 *str = gb_alloc_array(heap_allocator(), u8, base_dir.len+1+path.len+1);
|
||||
defer (gb_free(heap_allocator(), str));
|
||||
|
||||
@@ -1004,7 +1005,7 @@ String get_fullpath_relative(gbAllocator a, String base_dir, String path) {
|
||||
}
|
||||
|
||||
|
||||
String get_fullpath_core(gbAllocator a, String path) {
|
||||
gb_internal String get_fullpath_core(gbAllocator a, String path) {
|
||||
String module_dir = odin_root_dir();
|
||||
|
||||
String core = str_lit("core/");
|
||||
@@ -1024,11 +1025,11 @@ String get_fullpath_core(gbAllocator a, String path) {
|
||||
return path_to_fullpath(a, res);
|
||||
}
|
||||
|
||||
bool show_error_line(void) {
|
||||
gb_internal bool show_error_line(void) {
|
||||
return build_context.show_error_line;
|
||||
}
|
||||
|
||||
bool has_asm_extension(String const &path) {
|
||||
gb_internal bool has_asm_extension(String const &path) {
|
||||
String ext = path_extension(path);
|
||||
if (ext == ".asm") {
|
||||
return true;
|
||||
@@ -1041,7 +1042,7 @@ bool has_asm_extension(String const &path) {
|
||||
}
|
||||
|
||||
// temporary
|
||||
char *token_pos_to_string(TokenPos const &pos) {
|
||||
gb_internal char *token_pos_to_string(TokenPos const &pos) {
|
||||
gbString s = gb_string_make_reserve(temporary_allocator(), 128);
|
||||
String file = get_file_path_string(pos.file_id);
|
||||
switch (build_context.ODIN_ERROR_POS_STYLE) {
|
||||
@@ -1056,7 +1057,7 @@ char *token_pos_to_string(TokenPos const &pos) {
|
||||
return s;
|
||||
}
|
||||
|
||||
void init_build_context(TargetMetrics *cross_target) {
|
||||
gb_internal void init_build_context(TargetMetrics *cross_target) {
|
||||
BuildContext *bc = &build_context;
|
||||
|
||||
gb_affinity_init(&bc->affinity);
|
||||
@@ -1258,7 +1259,7 @@ void init_build_context(TargetMetrics *cross_target) {
|
||||
#endif
|
||||
|
||||
|
||||
Array<String> split_by_comma(String const &list) {
|
||||
gb_internal Array<String> split_by_comma(String const &list) {
|
||||
isize n = 1;
|
||||
for (isize i = 0; i < list.len; i++) {
|
||||
if (list.text[i] == ',') {
|
||||
@@ -1280,12 +1281,12 @@ Array<String> split_by_comma(String const &list) {
|
||||
return res;
|
||||
}
|
||||
|
||||
bool check_target_feature_is_valid(TokenPos pos, String const &feature) {
|
||||
gb_internal bool check_target_feature_is_valid(TokenPos pos, String const &feature) {
|
||||
// TODO(bill): check_target_feature_is_valid
|
||||
return true;
|
||||
}
|
||||
|
||||
bool check_target_feature_is_enabled(TokenPos pos, String const &target_feature_list) {
|
||||
gb_internal bool check_target_feature_is_enabled(TokenPos pos, String const &target_feature_list) {
|
||||
BuildContext *bc = &build_context;
|
||||
mutex_lock(&bc->target_features_mutex);
|
||||
defer (mutex_unlock(&bc->target_features_mutex));
|
||||
@@ -1307,7 +1308,7 @@ bool check_target_feature_is_enabled(TokenPos pos, String const &target_feature_
|
||||
return true;
|
||||
}
|
||||
|
||||
void enable_target_feature(TokenPos pos, String const &target_feature_list) {
|
||||
gb_internal void enable_target_feature(TokenPos pos, String const &target_feature_list) {
|
||||
BuildContext *bc = &build_context;
|
||||
mutex_lock(&bc->target_features_mutex);
|
||||
defer (mutex_unlock(&bc->target_features_mutex));
|
||||
@@ -1326,7 +1327,7 @@ void enable_target_feature(TokenPos pos, String const &target_feature_list) {
|
||||
}
|
||||
|
||||
|
||||
char const *target_features_set_to_cstring(gbAllocator allocator, bool with_quotes) {
|
||||
gb_internal char const *target_features_set_to_cstring(gbAllocator allocator, bool with_quotes) {
|
||||
isize len = 0;
|
||||
isize i = 0;
|
||||
for (auto const &entry : build_context.target_features_set) {
|
||||
@@ -1359,7 +1360,7 @@ char const *target_features_set_to_cstring(gbAllocator allocator, bool with_quot
|
||||
|
||||
// NOTE(Jeroen): Set/create the output and other paths and report an error as appropriate.
|
||||
// We've previously called `parse_build_flags`, so `out_filepath` should be set.
|
||||
bool init_build_paths(String init_filename) {
|
||||
gb_internal bool init_build_paths(String init_filename) {
|
||||
gbAllocator ha = heap_allocator();
|
||||
BuildContext *bc = &build_context;
|
||||
|
||||
|
||||
@@ -29,14 +29,14 @@
|
||||
#include <string.h>
|
||||
#include <atomic> // Because I wanted the C++11 memory order semantics, of which gb.h does not offer (because it was a C89 library)
|
||||
|
||||
gbAllocator heap_allocator(void);
|
||||
gb_internal gbAllocator heap_allocator(void);
|
||||
|
||||
#define for_array(index_, array_) for (isize index_ = 0; index_ < (array_).count; index_++)
|
||||
|
||||
i32 next_pow2(i32 n);
|
||||
i64 next_pow2(i64 n);
|
||||
isize next_pow2_isize(isize n);
|
||||
void debugf(char const *fmt, ...);
|
||||
gb_internal i32 next_pow2(i32 n);
|
||||
gb_internal i64 next_pow2(i64 n);
|
||||
gb_internal isize next_pow2_isize(isize n);
|
||||
gb_internal void debugf(char const *fmt, ...);
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS) && defined(GB_ARCH_32_BIT)
|
||||
#error Odin on Windows requires a 64-bit build-system. The 'Developer Command Prompt' for VS still defaults to 32-bit shell. The 64-bit shell can be found under the name 'x64 Native Tools Command Prompt' for VS. For more information, please see https://odin-lang.org/docs/install/#for-windows
|
||||
@@ -51,14 +51,14 @@ void debugf(char const *fmt, ...);
|
||||
#include "range_cache.cpp"
|
||||
|
||||
|
||||
bool is_power_of_two(i64 x) {
|
||||
gb_internal gb_inline bool is_power_of_two(i64 x) {
|
||||
if (x <= 0) {
|
||||
return false;
|
||||
}
|
||||
return !(x & (x-1));
|
||||
}
|
||||
|
||||
int isize_cmp(isize x, isize y) {
|
||||
gb_internal int isize_cmp(isize x, isize y) {
|
||||
if (x < y) {
|
||||
return -1;
|
||||
} else if (x > y) {
|
||||
@@ -66,7 +66,7 @@ int isize_cmp(isize x, isize y) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int u64_cmp(u64 x, u64 y) {
|
||||
gb_internal int u64_cmp(u64 x, u64 y) {
|
||||
if (x < y) {
|
||||
return -1;
|
||||
} else if (x > y) {
|
||||
@@ -74,7 +74,7 @@ int u64_cmp(u64 x, u64 y) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int i64_cmp(i64 x, i64 y) {
|
||||
gb_internal int i64_cmp(i64 x, i64 y) {
|
||||
if (x < y) {
|
||||
return -1;
|
||||
} else if (x > y) {
|
||||
@@ -82,7 +82,7 @@ int i64_cmp(i64 x, i64 y) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int i32_cmp(i32 x, i32 y) {
|
||||
gb_internal int i32_cmp(i32 x, i32 y) {
|
||||
if (x < y) {
|
||||
return -1;
|
||||
} else if (x > y) {
|
||||
@@ -91,7 +91,7 @@ int i32_cmp(i32 x, i32 y) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 fnv32a(void const *data, isize len) {
|
||||
gb_internal u32 fnv32a(void const *data, isize len) {
|
||||
u8 const *bytes = cast(u8 const *)data;
|
||||
u32 h = 0x811c9dc5;
|
||||
|
||||
@@ -112,7 +112,7 @@ u32 fnv32a(void const *data, isize len) {
|
||||
return h;
|
||||
}
|
||||
|
||||
u64 fnv64a(void const *data, isize len) {
|
||||
gb_internal u64 fnv64a(void const *data, isize len) {
|
||||
u8 const *bytes = cast(u8 const *)data;
|
||||
u64 h = 0xcbf29ce484222325ull;
|
||||
|
||||
@@ -133,7 +133,7 @@ u64 fnv64a(void const *data, isize len) {
|
||||
return h;
|
||||
}
|
||||
|
||||
u64 u64_digit_value(Rune r) {
|
||||
gb_internal u64 u64_digit_value(Rune r) {
|
||||
switch (r) {
|
||||
case '0': return 0;
|
||||
case '1': return 1;
|
||||
@@ -162,7 +162,7 @@ u64 u64_digit_value(Rune r) {
|
||||
}
|
||||
|
||||
|
||||
u64 u64_from_string(String string) {
|
||||
gb_internal u64 u64_from_string(String string) {
|
||||
u64 base = 10;
|
||||
bool has_prefix = false;
|
||||
if (string.len > 2 && string[0] == '0') {
|
||||
@@ -205,7 +205,7 @@ gb_global char const global_num_to_char_table[] =
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"@$";
|
||||
|
||||
String u64_to_string(u64 v, char *out_buf, isize out_buf_len) {
|
||||
gb_internal String u64_to_string(u64 v, char *out_buf, isize out_buf_len) {
|
||||
char buf[32] = {0};
|
||||
isize i = gb_size_of(buf);
|
||||
|
||||
@@ -220,7 +220,7 @@ String u64_to_string(u64 v, char *out_buf, isize out_buf_len) {
|
||||
gb_memmove(out_buf, &buf[i], len);
|
||||
return make_string(cast(u8 *)out_buf, len);
|
||||
}
|
||||
String i64_to_string(i64 a, char *out_buf, isize out_buf_len) {
|
||||
gb_internal String i64_to_string(i64 a, char *out_buf, isize out_buf_len) {
|
||||
char buf[32] = {0};
|
||||
isize i = gb_size_of(buf);
|
||||
bool negative = false;
|
||||
@@ -282,17 +282,17 @@ gb_global u64 const unsigned_integer_maxs[] = {
|
||||
};
|
||||
|
||||
|
||||
bool add_overflow_u64(u64 x, u64 y, u64 *result) {
|
||||
gb_internal bool add_overflow_u64(u64 x, u64 y, u64 *result) {
|
||||
*result = x + y;
|
||||
return *result < x || *result < y;
|
||||
}
|
||||
|
||||
bool sub_overflow_u64(u64 x, u64 y, u64 *result) {
|
||||
gb_internal bool sub_overflow_u64(u64 x, u64 y, u64 *result) {
|
||||
*result = x - y;
|
||||
return *result > x;
|
||||
}
|
||||
|
||||
void mul_overflow_u64(u64 x, u64 y, u64 *lo, u64 *hi) {
|
||||
gb_internal void mul_overflow_u64(u64 x, u64 y, u64 *lo, u64 *hi) {
|
||||
#if defined(GB_COMPILER_MSVC) && defined(GB_ARCH_64_BIT)
|
||||
*lo = _umul128(x, y, hi);
|
||||
#else
|
||||
@@ -342,7 +342,7 @@ struct StringIntern {
|
||||
PtrMap<uintptr, StringIntern *> string_intern_map = {}; // Key: u64
|
||||
gb_global Arena string_intern_arena = {};
|
||||
|
||||
char const *string_intern(char const *text, isize len) {
|
||||
gb_internal char const *string_intern(char const *text, isize len) {
|
||||
u64 hash = gb_fnv64a(text, len);
|
||||
uintptr key = cast(uintptr)(hash ? hash : 1);
|
||||
StringIntern **found = map_get(&string_intern_map, key);
|
||||
@@ -363,18 +363,18 @@ char const *string_intern(char const *text, isize len) {
|
||||
return new_intern->str;
|
||||
}
|
||||
|
||||
char const *string_intern(String const &string) {
|
||||
gb_internal char const *string_intern(String const &string) {
|
||||
return string_intern(cast(char const *)string.text, string.len);
|
||||
}
|
||||
|
||||
void init_string_interner(void) {
|
||||
gb_internal void init_string_interner(void) {
|
||||
map_init(&string_intern_map, heap_allocator());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
i32 next_pow2(i32 n) {
|
||||
gb_internal i32 next_pow2(i32 n) {
|
||||
if (n <= 0) {
|
||||
return 0;
|
||||
}
|
||||
@@ -387,7 +387,7 @@ i32 next_pow2(i32 n) {
|
||||
n++;
|
||||
return n;
|
||||
}
|
||||
i64 next_pow2(i64 n) {
|
||||
gb_internal i64 next_pow2(i64 n) {
|
||||
if (n <= 0) {
|
||||
return 0;
|
||||
}
|
||||
@@ -401,7 +401,7 @@ i64 next_pow2(i64 n) {
|
||||
n++;
|
||||
return n;
|
||||
}
|
||||
isize next_pow2_isize(isize n) {
|
||||
gb_internal isize next_pow2_isize(isize n) {
|
||||
if (n <= 0) {
|
||||
return 0;
|
||||
}
|
||||
@@ -417,7 +417,7 @@ isize next_pow2_isize(isize n) {
|
||||
n++;
|
||||
return n;
|
||||
}
|
||||
u32 next_pow2_u32(u32 n) {
|
||||
gb_internal u32 next_pow2_u32(u32 n) {
|
||||
if (n == 0) {
|
||||
return 0;
|
||||
}
|
||||
@@ -432,7 +432,7 @@ u32 next_pow2_u32(u32 n) {
|
||||
}
|
||||
|
||||
|
||||
i32 bit_set_count(u32 x) {
|
||||
gb_internal i32 bit_set_count(u32 x) {
|
||||
x -= ((x >> 1) & 0x55555555);
|
||||
x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
|
||||
x = (((x >> 4) + x) & 0x0f0f0f0f);
|
||||
@@ -442,13 +442,13 @@ i32 bit_set_count(u32 x) {
|
||||
return cast(i32)(x & 0x0000003f);
|
||||
}
|
||||
|
||||
i64 bit_set_count(u64 x) {
|
||||
gb_internal i64 bit_set_count(u64 x) {
|
||||
u32 a = *(cast(u32 *)&x);
|
||||
u32 b = *(cast(u32 *)&x + 1);
|
||||
return bit_set_count(a) + bit_set_count(b);
|
||||
}
|
||||
|
||||
u32 floor_log2(u32 x) {
|
||||
gb_internal u32 floor_log2(u32 x) {
|
||||
x |= x >> 1;
|
||||
x |= x >> 2;
|
||||
x |= x >> 4;
|
||||
@@ -457,7 +457,7 @@ u32 floor_log2(u32 x) {
|
||||
return cast(u32)(bit_set_count(x) - 1);
|
||||
}
|
||||
|
||||
u64 floor_log2(u64 x) {
|
||||
gb_internal u64 floor_log2(u64 x) {
|
||||
x |= x >> 1;
|
||||
x |= x >> 2;
|
||||
x |= x >> 4;
|
||||
@@ -468,7 +468,7 @@ u64 floor_log2(u64 x) {
|
||||
}
|
||||
|
||||
|
||||
u32 ceil_log2(u32 x) {
|
||||
gb_internal u32 ceil_log2(u32 x) {
|
||||
i32 y = cast(i32)(x & (x-1));
|
||||
y |= -y;
|
||||
y >>= 32-1;
|
||||
@@ -480,7 +480,7 @@ u32 ceil_log2(u32 x) {
|
||||
return cast(u32)(bit_set_count(x) - 1 - y);
|
||||
}
|
||||
|
||||
u64 ceil_log2(u64 x) {
|
||||
gb_internal u64 ceil_log2(u64 x) {
|
||||
i64 y = cast(i64)(x & (x-1));
|
||||
y |= -y;
|
||||
y >>= 64-1;
|
||||
@@ -493,7 +493,7 @@ u64 ceil_log2(u64 x) {
|
||||
return cast(u64)(bit_set_count(x) - 1 - y);
|
||||
}
|
||||
|
||||
u32 prev_pow2(u32 n) {
|
||||
gb_internal u32 prev_pow2(u32 n) {
|
||||
if (n == 0) {
|
||||
return 0;
|
||||
}
|
||||
@@ -504,7 +504,7 @@ u32 prev_pow2(u32 n) {
|
||||
n |= n >> 16;
|
||||
return n - (n >> 1);
|
||||
}
|
||||
i32 prev_pow2(i32 n) {
|
||||
gb_internal i32 prev_pow2(i32 n) {
|
||||
if (n <= 0) {
|
||||
return 0;
|
||||
}
|
||||
@@ -515,7 +515,7 @@ i32 prev_pow2(i32 n) {
|
||||
n |= n >> 16;
|
||||
return n - (n >> 1);
|
||||
}
|
||||
i64 prev_pow2(i64 n) {
|
||||
gb_internal i64 prev_pow2(i64 n) {
|
||||
if (n <= 0) {
|
||||
return 0;
|
||||
}
|
||||
@@ -528,7 +528,7 @@ i64 prev_pow2(i64 n) {
|
||||
return n - (n >> 1);
|
||||
}
|
||||
|
||||
u16 f32_to_f16(f32 value) {
|
||||
gb_internal u16 f32_to_f16(f32 value) {
|
||||
union { u32 i; f32 f; } v;
|
||||
i32 i, s, e, m;
|
||||
|
||||
@@ -579,7 +579,7 @@ u16 f32_to_f16(f32 value) {
|
||||
}
|
||||
}
|
||||
|
||||
f32 f16_to_f32(u16 value) {
|
||||
gb_internal f32 f16_to_f32(u16 value) {
|
||||
typedef union { u32 u; f32 f; } fp32;
|
||||
fp32 v;
|
||||
|
||||
@@ -595,7 +595,7 @@ f32 f16_to_f32(u16 value) {
|
||||
return v.f;
|
||||
}
|
||||
|
||||
f64 gb_sqrt(f64 x) {
|
||||
gb_internal gb_inline f64 gb_sqrt(f64 x) {
|
||||
return sqrt(x);
|
||||
}
|
||||
|
||||
@@ -623,7 +623,7 @@ f64 gb_sqrt(f64 x) {
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
|
||||
wchar_t **command_line_to_wargv(wchar_t *cmd_line, int *_argc) {
|
||||
gb_internal wchar_t **command_line_to_wargv(wchar_t *cmd_line, int *_argc) {
|
||||
u32 i, j;
|
||||
|
||||
u32 len = cast(u32)string16_len(cmd_line);
|
||||
@@ -706,7 +706,7 @@ enum LoadedFileError {
|
||||
LoadedFile_COUNT,
|
||||
};
|
||||
|
||||
LoadedFileError load_file_32(char const *fullpath, LoadedFile *memory_mapped_file, bool copy_file_contents) {
|
||||
gb_internal LoadedFileError load_file_32(char const *fullpath, LoadedFile *memory_mapped_file, bool copy_file_contents) {
|
||||
LoadedFileError err = LoadedFile_None;
|
||||
|
||||
if (!copy_file_contents) {
|
||||
@@ -811,7 +811,7 @@ LoadedFileError load_file_32(char const *fullpath, LoadedFile *memory_mapped_fil
|
||||
|
||||
#define USE_DAMERAU_LEVENSHTEIN 1
|
||||
|
||||
isize levenstein_distance_case_insensitive(String const &a, String const &b) {
|
||||
gb_internal isize levenstein_distance_case_insensitive(String const &a, String const &b) {
|
||||
isize w = b.len+1;
|
||||
isize h = a.len+1;
|
||||
isize *matrix = gb_alloc_array(temporary_allocator(), isize, w*h);
|
||||
@@ -870,16 +870,16 @@ struct DidYouMeanAnswers {
|
||||
|
||||
enum {MAX_SMALLEST_DID_YOU_MEAN_DISTANCE = 3-USE_DAMERAU_LEVENSHTEIN};
|
||||
|
||||
DidYouMeanAnswers did_you_mean_make(gbAllocator allocator, isize cap, String const &key) {
|
||||
gb_internal DidYouMeanAnswers did_you_mean_make(gbAllocator allocator, isize cap, String const &key) {
|
||||
DidYouMeanAnswers d = {};
|
||||
array_init(&d.distances, allocator, 0, cap);
|
||||
d.key = key;
|
||||
return d;
|
||||
}
|
||||
void did_you_mean_destroy(DidYouMeanAnswers *d) {
|
||||
gb_internal void did_you_mean_destroy(DidYouMeanAnswers *d) {
|
||||
array_free(&d->distances);
|
||||
}
|
||||
void did_you_mean_append(DidYouMeanAnswers *d, String const &target) {
|
||||
gb_internal void did_you_mean_append(DidYouMeanAnswers *d, String const &target) {
|
||||
if (target.len == 0 || target == "_") {
|
||||
return;
|
||||
}
|
||||
@@ -888,7 +888,7 @@ void did_you_mean_append(DidYouMeanAnswers *d, String const &target) {
|
||||
dat.distance = levenstein_distance_case_insensitive(d->key, target);
|
||||
array_add(&d->distances, dat);
|
||||
}
|
||||
Slice<DistanceAndTarget> did_you_mean_results(DidYouMeanAnswers *d) {
|
||||
gb_internal Slice<DistanceAndTarget> did_you_mean_results(DidYouMeanAnswers *d) {
|
||||
gb_sort_array(d->distances.data, d->distances.count, gb_isize_cmp(gb_offset_of(DistanceAndTarget, distance)));
|
||||
isize count = 0;
|
||||
for (isize i = 0; i < d->distances.count; i++) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
gb_inline void zero_size(void *ptr, isize len) {
|
||||
gb_internal gb_inline void zero_size(void *ptr, isize len) {
|
||||
memset(ptr, 0, len);
|
||||
}
|
||||
|
||||
@@ -7,27 +7,27 @@ gb_inline void zero_size(void *ptr, isize len) {
|
||||
|
||||
|
||||
template <typename U, typename V>
|
||||
gb_inline U bit_cast(V &v) { return reinterpret_cast<U &>(v); }
|
||||
gb_internal gb_inline U bit_cast(V &v) { return reinterpret_cast<U &>(v); }
|
||||
|
||||
template <typename U, typename V>
|
||||
gb_inline U const &bit_cast(V const &v) { return reinterpret_cast<U const &>(v); }
|
||||
gb_internal gb_inline U const &bit_cast(V const &v) { return reinterpret_cast<U const &>(v); }
|
||||
|
||||
|
||||
gb_inline i64 align_formula(i64 size, i64 align) {
|
||||
gb_internal gb_inline i64 align_formula(i64 size, i64 align) {
|
||||
if (align > 0) {
|
||||
i64 result = size + align-1;
|
||||
return result - result%align;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
gb_inline isize align_formula_isize(isize size, isize align) {
|
||||
gb_internal gb_inline isize align_formula_isize(isize size, isize align) {
|
||||
if (align > 0) {
|
||||
isize result = size + align-1;
|
||||
return result - result%align;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
gb_inline void *align_formula_ptr(void *ptr, isize align) {
|
||||
gb_internal gb_inline void *align_formula_ptr(void *ptr, isize align) {
|
||||
if (align > 0) {
|
||||
uintptr result = (cast(uintptr)ptr) + align-1;
|
||||
return (void *)(result - result%align);
|
||||
@@ -39,9 +39,9 @@ gb_inline void *align_formula_ptr(void *ptr, isize align) {
|
||||
gb_global BlockingMutex global_memory_block_mutex;
|
||||
gb_global BlockingMutex global_memory_allocator_mutex;
|
||||
|
||||
void platform_virtual_memory_init(void);
|
||||
gb_internal void platform_virtual_memory_init(void);
|
||||
|
||||
void virtual_memory_init(void) {
|
||||
gb_internal void virtual_memory_init(void) {
|
||||
mutex_init(&global_memory_block_mutex);
|
||||
mutex_init(&global_memory_allocator_mutex);
|
||||
platform_virtual_memory_init();
|
||||
@@ -66,13 +66,13 @@ enum { DEFAULT_MINIMUM_BLOCK_SIZE = 8ll*1024ll*1024ll };
|
||||
|
||||
gb_global isize DEFAULT_PAGE_SIZE = 4096;
|
||||
|
||||
MemoryBlock *virtual_memory_alloc(isize size);
|
||||
void virtual_memory_dealloc(MemoryBlock *block);
|
||||
void *arena_alloc(Arena *arena, isize min_size, isize alignment);
|
||||
void arena_free_all(Arena *arena);
|
||||
gb_internal MemoryBlock *virtual_memory_alloc(isize size);
|
||||
gb_internal void virtual_memory_dealloc(MemoryBlock *block);
|
||||
gb_internal void *arena_alloc(Arena *arena, isize min_size, isize alignment);
|
||||
gb_internal void arena_free_all(Arena *arena);
|
||||
|
||||
|
||||
isize arena_align_forward_offset(Arena *arena, isize alignment) {
|
||||
gb_internal isize arena_align_forward_offset(Arena *arena, isize alignment) {
|
||||
isize alignment_offset = 0;
|
||||
isize ptr = cast(isize)(arena->curr_block->base + arena->curr_block->used);
|
||||
isize mask = alignment-1;
|
||||
@@ -82,7 +82,7 @@ isize arena_align_forward_offset(Arena *arena, isize alignment) {
|
||||
return alignment_offset;
|
||||
}
|
||||
|
||||
void *arena_alloc(Arena *arena, isize min_size, isize alignment) {
|
||||
gb_internal void *arena_alloc(Arena *arena, isize min_size, isize alignment) {
|
||||
GB_ASSERT(gb_is_power_of_two(alignment));
|
||||
|
||||
BlockingMutex *mutex = &global_memory_allocator_mutex;
|
||||
@@ -123,7 +123,7 @@ void *arena_alloc(Arena *arena, isize min_size, isize alignment) {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void arena_free_all(Arena *arena) {
|
||||
gb_internal void arena_free_all(Arena *arena) {
|
||||
while (arena->curr_block != nullptr) {
|
||||
MemoryBlock *free_block = arena->curr_block;
|
||||
arena->curr_block = free_block->prev;
|
||||
@@ -142,12 +142,12 @@ struct PlatformMemoryBlock {
|
||||
gb_global std::atomic<isize> global_platform_memory_total_usage;
|
||||
gb_global PlatformMemoryBlock global_platform_memory_block_sentinel;
|
||||
|
||||
PlatformMemoryBlock *platform_virtual_memory_alloc(isize total_size);
|
||||
void platform_virtual_memory_free(PlatformMemoryBlock *block);
|
||||
void platform_virtual_memory_protect(void *memory, isize size);
|
||||
gb_internal PlatformMemoryBlock *platform_virtual_memory_alloc(isize total_size);
|
||||
gb_internal void platform_virtual_memory_free(PlatformMemoryBlock *block);
|
||||
gb_internal void platform_virtual_memory_protect(void *memory, isize size);
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
void platform_virtual_memory_init(void) {
|
||||
gb_internal void platform_virtual_memory_init(void) {
|
||||
global_platform_memory_block_sentinel.prev = &global_platform_memory_block_sentinel;
|
||||
global_platform_memory_block_sentinel.next = &global_platform_memory_block_sentinel;
|
||||
|
||||
@@ -157,7 +157,7 @@ void platform_virtual_memory_protect(void *memory, isize size);
|
||||
GB_ASSERT(gb_is_power_of_two(DEFAULT_PAGE_SIZE));
|
||||
}
|
||||
|
||||
PlatformMemoryBlock *platform_virtual_memory_alloc(isize total_size) {
|
||||
gb_internal PlatformMemoryBlock *platform_virtual_memory_alloc(isize total_size) {
|
||||
PlatformMemoryBlock *pmblock = (PlatformMemoryBlock *)VirtualAlloc(0, total_size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
|
||||
if (pmblock == nullptr) {
|
||||
gb_printf_err("Out of Virtual memory, oh no...\n");
|
||||
@@ -168,17 +168,17 @@ void platform_virtual_memory_protect(void *memory, isize size);
|
||||
global_platform_memory_total_usage += total_size;
|
||||
return pmblock;
|
||||
}
|
||||
void platform_virtual_memory_free(PlatformMemoryBlock *block) {
|
||||
gb_internal void platform_virtual_memory_free(PlatformMemoryBlock *block) {
|
||||
global_platform_memory_total_usage -= block->total_size;
|
||||
GB_ASSERT(VirtualFree(block, 0, MEM_RELEASE));
|
||||
}
|
||||
void platform_virtual_memory_protect(void *memory, isize size) {
|
||||
gb_internal void platform_virtual_memory_protect(void *memory, isize size) {
|
||||
DWORD old_protect = 0;
|
||||
BOOL is_protected = VirtualProtect(memory, size, PAGE_NOACCESS, &old_protect);
|
||||
GB_ASSERT(is_protected);
|
||||
}
|
||||
#else
|
||||
void platform_virtual_memory_init(void) {
|
||||
gb_internal void platform_virtual_memory_init(void) {
|
||||
global_platform_memory_block_sentinel.prev = &global_platform_memory_block_sentinel;
|
||||
global_platform_memory_block_sentinel.next = &global_platform_memory_block_sentinel;
|
||||
|
||||
@@ -186,7 +186,7 @@ void platform_virtual_memory_protect(void *memory, isize size);
|
||||
GB_ASSERT(gb_is_power_of_two(DEFAULT_PAGE_SIZE));
|
||||
}
|
||||
|
||||
PlatformMemoryBlock *platform_virtual_memory_alloc(isize total_size) {
|
||||
gb_internal PlatformMemoryBlock *platform_virtual_memory_alloc(isize total_size) {
|
||||
PlatformMemoryBlock *pmblock = (PlatformMemoryBlock *)mmap(nullptr, total_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
||||
if (pmblock == nullptr) {
|
||||
gb_printf_err("Out of Virtual memory, oh no...\n");
|
||||
@@ -197,18 +197,18 @@ void platform_virtual_memory_protect(void *memory, isize size);
|
||||
global_platform_memory_total_usage += total_size;
|
||||
return pmblock;
|
||||
}
|
||||
void platform_virtual_memory_free(PlatformMemoryBlock *block) {
|
||||
gb_internal void platform_virtual_memory_free(PlatformMemoryBlock *block) {
|
||||
isize size = block->total_size;
|
||||
global_platform_memory_total_usage -= size;
|
||||
munmap(block, size);
|
||||
}
|
||||
void platform_virtual_memory_protect(void *memory, isize size) {
|
||||
gb_internal void platform_virtual_memory_protect(void *memory, isize size) {
|
||||
int err = mprotect(memory, size, PROT_NONE);
|
||||
GB_ASSERT(err == 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
MemoryBlock *virtual_memory_alloc(isize size) {
|
||||
gb_internal MemoryBlock *virtual_memory_alloc(isize size) {
|
||||
isize const page_size = DEFAULT_PAGE_SIZE;
|
||||
|
||||
isize total_size = size + gb_size_of(PlatformMemoryBlock);
|
||||
@@ -250,7 +250,7 @@ MemoryBlock *virtual_memory_alloc(isize size) {
|
||||
return &pmblock->block;
|
||||
}
|
||||
|
||||
void virtual_memory_dealloc(MemoryBlock *block_to_free) {
|
||||
gb_internal void virtual_memory_dealloc(MemoryBlock *block_to_free) {
|
||||
PlatformMemoryBlock *block = cast(PlatformMemoryBlock *)block_to_free;
|
||||
if (block != nullptr) {
|
||||
mutex_lock(&global_memory_block_mutex);
|
||||
@@ -265,9 +265,9 @@ void virtual_memory_dealloc(MemoryBlock *block_to_free) {
|
||||
|
||||
|
||||
|
||||
GB_ALLOCATOR_PROC(arena_allocator_proc);
|
||||
gb_internal GB_ALLOCATOR_PROC(arena_allocator_proc);
|
||||
|
||||
gbAllocator arena_allocator(Arena *arena) {
|
||||
gb_internal gbAllocator arena_allocator(Arena *arena) {
|
||||
gbAllocator a;
|
||||
a.proc = arena_allocator_proc;
|
||||
a.data = arena;
|
||||
@@ -275,7 +275,7 @@ gbAllocator arena_allocator(Arena *arena) {
|
||||
}
|
||||
|
||||
|
||||
GB_ALLOCATOR_PROC(arena_allocator_proc) {
|
||||
gb_internal GB_ALLOCATOR_PROC(arena_allocator_proc) {
|
||||
void *ptr = nullptr;
|
||||
Arena *arena = cast(Arena *)allocator_data;
|
||||
GB_ASSERT_NOT_NULL(arena);
|
||||
@@ -307,11 +307,11 @@ GB_ALLOCATOR_PROC(arena_allocator_proc) {
|
||||
|
||||
|
||||
gb_global gb_thread_local Arena permanent_arena = {nullptr, DEFAULT_MINIMUM_BLOCK_SIZE, true};
|
||||
gbAllocator permanent_allocator() {
|
||||
gb_internal gbAllocator permanent_allocator() {
|
||||
return arena_allocator(&permanent_arena);
|
||||
}
|
||||
|
||||
gbAllocator temporary_allocator() {
|
||||
gb_internal gbAllocator temporary_allocator() {
|
||||
return permanent_allocator();
|
||||
}
|
||||
|
||||
@@ -320,9 +320,9 @@ gbAllocator temporary_allocator() {
|
||||
|
||||
|
||||
|
||||
GB_ALLOCATOR_PROC(heap_allocator_proc);
|
||||
gb_internal GB_ALLOCATOR_PROC(heap_allocator_proc);
|
||||
|
||||
gbAllocator heap_allocator(void) {
|
||||
gb_internal gbAllocator heap_allocator(void) {
|
||||
gbAllocator a;
|
||||
a.proc = heap_allocator_proc;
|
||||
a.data = nullptr;
|
||||
@@ -330,7 +330,7 @@ gbAllocator heap_allocator(void) {
|
||||
}
|
||||
|
||||
|
||||
GB_ALLOCATOR_PROC(heap_allocator_proc) {
|
||||
gb_internal GB_ALLOCATOR_PROC(heap_allocator_proc) {
|
||||
void *ptr = nullptr;
|
||||
gb_unused(allocator_data);
|
||||
gb_unused(old_size);
|
||||
@@ -460,7 +460,7 @@ GB_ALLOCATOR_PROC(heap_allocator_proc) {
|
||||
|
||||
|
||||
template <typename T>
|
||||
void resize_array_raw(T **array, gbAllocator const &a, isize old_count, isize new_count) {
|
||||
gb_internal void resize_array_raw(T **array, gbAllocator const &a, isize old_count, isize new_count) {
|
||||
GB_ASSERT(new_count >= 0);
|
||||
if (new_count == 0) {
|
||||
gb_free(a, *array);
|
||||
|
||||
@@ -17,11 +17,11 @@ gb_global ErrorCollector global_error_collector;
|
||||
#define MAX_ERROR_COLLECTOR_COUNT (36)
|
||||
|
||||
|
||||
bool any_errors(void) {
|
||||
gb_internal bool any_errors(void) {
|
||||
return global_error_collector.count.load() != 0;
|
||||
}
|
||||
|
||||
void init_global_error_collector(void) {
|
||||
gb_internal void init_global_error_collector(void) {
|
||||
mutex_init(&global_error_collector.mutex);
|
||||
mutex_init(&global_error_collector.block_mutex);
|
||||
mutex_init(&global_error_collector.error_out_mutex);
|
||||
@@ -35,9 +35,9 @@ void init_global_error_collector(void) {
|
||||
|
||||
// temporary
|
||||
// defined in build_settings.cpp
|
||||
char *token_pos_to_string(TokenPos const &pos);
|
||||
gb_internal char *token_pos_to_string(TokenPos const &pos);
|
||||
|
||||
bool set_file_path_string(i32 index, String const &path) {
|
||||
gb_internal bool set_file_path_string(i32 index, String const &path) {
|
||||
bool ok = false;
|
||||
GB_ASSERT(index >= 0);
|
||||
mutex_lock(&global_error_collector.string_mutex);
|
||||
@@ -55,7 +55,7 @@ bool set_file_path_string(i32 index, String const &path) {
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool thread_safe_set_ast_file_from_id(i32 index, AstFile *file) {
|
||||
gb_internal bool thread_safe_set_ast_file_from_id(i32 index, AstFile *file) {
|
||||
bool ok = false;
|
||||
GB_ASSERT(index >= 0);
|
||||
mutex_lock(&global_error_collector.string_mutex);
|
||||
@@ -73,7 +73,7 @@ bool thread_safe_set_ast_file_from_id(i32 index, AstFile *file) {
|
||||
return ok;
|
||||
}
|
||||
|
||||
String get_file_path_string(i32 index) {
|
||||
gb_internal String get_file_path_string(i32 index) {
|
||||
GB_ASSERT(index >= 0);
|
||||
mutex_lock(&global_error_collector.string_mutex);
|
||||
|
||||
@@ -86,7 +86,7 @@ String get_file_path_string(i32 index) {
|
||||
return path;
|
||||
}
|
||||
|
||||
AstFile *thread_safe_get_ast_file_from_id(i32 index) {
|
||||
gb_internal AstFile *thread_safe_get_ast_file_from_id(i32 index) {
|
||||
GB_ASSERT(index >= 0);
|
||||
mutex_lock(&global_error_collector.string_mutex);
|
||||
|
||||
@@ -101,12 +101,12 @@ AstFile *thread_safe_get_ast_file_from_id(i32 index) {
|
||||
|
||||
|
||||
|
||||
void begin_error_block(void) {
|
||||
gb_internal void begin_error_block(void) {
|
||||
mutex_lock(&global_error_collector.block_mutex);
|
||||
global_error_collector.in_block.store(true);
|
||||
}
|
||||
|
||||
void end_error_block(void) {
|
||||
gb_internal void end_error_block(void) {
|
||||
if (global_error_collector.error_buffer.count > 0) {
|
||||
isize n = global_error_collector.error_buffer.count;
|
||||
u8 *text = gb_alloc_array(permanent_allocator(), u8, n+1);
|
||||
@@ -127,7 +127,7 @@ void end_error_block(void) {
|
||||
#define ERROR_OUT_PROC(name) void name(char const *fmt, va_list va)
|
||||
typedef ERROR_OUT_PROC(ErrorOutProc);
|
||||
|
||||
ERROR_OUT_PROC(default_error_out_va) {
|
||||
gb_internal ERROR_OUT_PROC(default_error_out_va) {
|
||||
gbFile *f = gb_file_get_standard(gbFileStandard_Error);
|
||||
|
||||
char buf[4096] = {};
|
||||
@@ -154,15 +154,15 @@ ERROR_OUT_PROC(default_error_out_va) {
|
||||
}
|
||||
|
||||
|
||||
ErrorOutProc *error_out_va = default_error_out_va;
|
||||
gb_global ErrorOutProc *error_out_va = default_error_out_va;
|
||||
|
||||
// NOTE: defined in build_settings.cpp
|
||||
bool global_warnings_as_errors(void);
|
||||
bool global_ignore_warnings(void);
|
||||
bool show_error_line(void);
|
||||
gbString get_file_line_as_string(TokenPos const &pos, i32 *offset);
|
||||
gb_internal bool global_warnings_as_errors(void);
|
||||
gb_internal bool global_ignore_warnings(void);
|
||||
gb_internal bool show_error_line(void);
|
||||
gb_internal gbString get_file_line_as_string(TokenPos const &pos, i32 *offset);
|
||||
|
||||
void error_out(char const *fmt, ...) {
|
||||
gb_internal void error_out(char const *fmt, ...) {
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
error_out_va(fmt, va);
|
||||
@@ -170,7 +170,7 @@ void error_out(char const *fmt, ...) {
|
||||
}
|
||||
|
||||
|
||||
bool show_error_on_line(TokenPos const &pos, TokenPos end) {
|
||||
gb_internal bool show_error_on_line(TokenPos const &pos, TokenPos end) {
|
||||
if (!show_error_line()) {
|
||||
return false;
|
||||
}
|
||||
@@ -237,7 +237,7 @@ bool show_error_on_line(TokenPos const &pos, TokenPos end) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void error_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) {
|
||||
gb_internal void error_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) {
|
||||
global_error_collector.count.fetch_add(1);
|
||||
|
||||
mutex_lock(&global_error_collector.mutex);
|
||||
@@ -257,7 +257,7 @@ void error_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) {
|
||||
}
|
||||
}
|
||||
|
||||
void warning_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) {
|
||||
gb_internal void warning_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) {
|
||||
if (global_warnings_as_errors()) {
|
||||
error_va(pos, end, fmt, va);
|
||||
return;
|
||||
@@ -280,11 +280,11 @@ void warning_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va)
|
||||
}
|
||||
|
||||
|
||||
void error_line_va(char const *fmt, va_list va) {
|
||||
gb_internal void error_line_va(char const *fmt, va_list va) {
|
||||
error_out_va(fmt, va);
|
||||
}
|
||||
|
||||
void error_no_newline_va(TokenPos const &pos, char const *fmt, va_list va) {
|
||||
gb_internal void error_no_newline_va(TokenPos const &pos, char const *fmt, va_list va) {
|
||||
mutex_lock(&global_error_collector.mutex);
|
||||
global_error_collector.count++;
|
||||
// NOTE(bill): Duplicate error, skip it
|
||||
@@ -303,7 +303,7 @@ void error_no_newline_va(TokenPos const &pos, char const *fmt, va_list va) {
|
||||
}
|
||||
|
||||
|
||||
void syntax_error_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) {
|
||||
gb_internal void syntax_error_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) {
|
||||
mutex_lock(&global_error_collector.mutex);
|
||||
global_error_collector.count++;
|
||||
// NOTE(bill): Duplicate error, skip it
|
||||
@@ -323,7 +323,7 @@ void syntax_error_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list
|
||||
}
|
||||
}
|
||||
|
||||
void syntax_warning_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) {
|
||||
gb_internal void syntax_warning_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) {
|
||||
if (global_warnings_as_errors()) {
|
||||
syntax_error_va(pos, end, fmt, va);
|
||||
return;
|
||||
@@ -347,21 +347,21 @@ void syntax_warning_va(TokenPos const &pos, TokenPos end, char const *fmt, va_li
|
||||
|
||||
|
||||
|
||||
void warning(Token const &token, char const *fmt, ...) {
|
||||
gb_internal void warning(Token const &token, char const *fmt, ...) {
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
warning_va(token.pos, {}, fmt, va);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
void error(Token const &token, char const *fmt, ...) {
|
||||
gb_internal void error(Token const &token, char const *fmt, ...) {
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
error_va(token.pos, {}, fmt, va);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
void error(TokenPos pos, char const *fmt, ...) {
|
||||
gb_internal void error(TokenPos pos, char const *fmt, ...) {
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
Token token = {};
|
||||
@@ -370,7 +370,7 @@ void error(TokenPos pos, char const *fmt, ...) {
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
void error_line(char const *fmt, ...) {
|
||||
gb_internal void error_line(char const *fmt, ...) {
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
error_line_va(fmt, va);
|
||||
@@ -378,21 +378,21 @@ void error_line(char const *fmt, ...) {
|
||||
}
|
||||
|
||||
|
||||
void syntax_error(Token const &token, char const *fmt, ...) {
|
||||
gb_internal void syntax_error(Token const &token, char const *fmt, ...) {
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
syntax_error_va(token.pos, {}, fmt, va);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
void syntax_error(TokenPos pos, char const *fmt, ...) {
|
||||
gb_internal void syntax_error(TokenPos pos, char const *fmt, ...) {
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
syntax_error_va(pos, {}, fmt, va);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
void syntax_warning(Token const &token, char const *fmt, ...) {
|
||||
gb_internal void syntax_warning(Token const &token, char const *fmt, ...) {
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
syntax_warning_va(token.pos, {}, fmt, va);
|
||||
@@ -400,7 +400,7 @@ void syntax_warning(Token const &token, char const *fmt, ...) {
|
||||
}
|
||||
|
||||
|
||||
void compiler_error(char const *fmt, ...) {
|
||||
gb_internal void compiler_error(char const *fmt, ...) {
|
||||
va_list va;
|
||||
|
||||
va_start(va, fmt);
|
||||
|
||||
@@ -15,7 +15,7 @@ struct Quaternion256 {
|
||||
f64 imag, jmag, kmag, real;
|
||||
};
|
||||
|
||||
Quaternion256 quaternion256_inverse(Quaternion256 x) {
|
||||
gb_internal Quaternion256 quaternion256_inverse(Quaternion256 x) {
|
||||
f64 invmag2 = 1.0 / (x.real*x.real + x.imag*x.imag + x.jmag*x.jmag + x.kmag*x.kmag);
|
||||
x.real = +x.real * invmag2;
|
||||
x.imag = -x.imag * invmag2;
|
||||
@@ -60,7 +60,7 @@ struct ExactValue {
|
||||
|
||||
gb_global ExactValue const empty_exact_value = {};
|
||||
|
||||
uintptr hash_exact_value(ExactValue v) {
|
||||
gb_internal uintptr hash_exact_value(ExactValue v) {
|
||||
mutex_lock(&hash_exact_value_mutex);
|
||||
defer (mutex_unlock(&hash_exact_value_mutex));
|
||||
|
||||
@@ -97,44 +97,44 @@ uintptr hash_exact_value(ExactValue v) {
|
||||
}
|
||||
|
||||
|
||||
ExactValue exact_value_compound(Ast *node) {
|
||||
gb_internal ExactValue exact_value_compound(Ast *node) {
|
||||
ExactValue result = {ExactValue_Compound};
|
||||
result.value_compound = node;
|
||||
return result;
|
||||
}
|
||||
|
||||
ExactValue exact_value_bool(bool b) {
|
||||
gb_internal ExactValue exact_value_bool(bool b) {
|
||||
ExactValue result = {ExactValue_Bool};
|
||||
result.value_bool = (b != 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
ExactValue exact_value_string(String string) {
|
||||
gb_internal ExactValue exact_value_string(String string) {
|
||||
// TODO(bill): Allow for numbers with underscores in them
|
||||
ExactValue result = {ExactValue_String};
|
||||
result.value_string = string;
|
||||
return result;
|
||||
}
|
||||
|
||||
ExactValue exact_value_i64(i64 i) {
|
||||
gb_internal ExactValue exact_value_i64(i64 i) {
|
||||
ExactValue result = {ExactValue_Integer};
|
||||
big_int_from_i64(&result.value_integer, i);
|
||||
return result;
|
||||
}
|
||||
|
||||
ExactValue exact_value_u64(u64 i) {
|
||||
gb_internal ExactValue exact_value_u64(u64 i) {
|
||||
ExactValue result = {ExactValue_Integer};
|
||||
big_int_from_u64(&result.value_integer, i);
|
||||
return result;
|
||||
}
|
||||
|
||||
ExactValue exact_value_float(f64 f) {
|
||||
gb_internal ExactValue exact_value_float(f64 f) {
|
||||
ExactValue result = {ExactValue_Float};
|
||||
result.value_float = f;
|
||||
return result;
|
||||
}
|
||||
|
||||
ExactValue exact_value_complex(f64 real, f64 imag) {
|
||||
gb_internal ExactValue exact_value_complex(f64 real, f64 imag) {
|
||||
ExactValue result = {ExactValue_Complex};
|
||||
result.value_complex = gb_alloc_item(permanent_allocator(), Complex128);
|
||||
result.value_complex->real = real;
|
||||
@@ -142,7 +142,7 @@ ExactValue exact_value_complex(f64 real, f64 imag) {
|
||||
return result;
|
||||
}
|
||||
|
||||
ExactValue exact_value_quaternion(f64 real, f64 imag, f64 jmag, f64 kmag) {
|
||||
gb_internal ExactValue exact_value_quaternion(f64 real, f64 imag, f64 jmag, f64 kmag) {
|
||||
ExactValue result = {ExactValue_Quaternion};
|
||||
result.value_quaternion = gb_alloc_item(permanent_allocator(), Quaternion256);
|
||||
result.value_quaternion->real = real;
|
||||
@@ -152,27 +152,27 @@ ExactValue exact_value_quaternion(f64 real, f64 imag, f64 jmag, f64 kmag) {
|
||||
return result;
|
||||
}
|
||||
|
||||
ExactValue exact_value_pointer(i64 ptr) {
|
||||
gb_internal ExactValue exact_value_pointer(i64 ptr) {
|
||||
ExactValue result = {ExactValue_Pointer};
|
||||
result.value_pointer = ptr;
|
||||
return result;
|
||||
}
|
||||
|
||||
ExactValue exact_value_procedure(Ast *node) {
|
||||
gb_internal ExactValue exact_value_procedure(Ast *node) {
|
||||
ExactValue result = {ExactValue_Procedure};
|
||||
result.value_procedure = node;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
ExactValue exact_value_typeid(Type *type) {
|
||||
gb_internal ExactValue exact_value_typeid(Type *type) {
|
||||
ExactValue result = {ExactValue_Typeid};
|
||||
result.value_typeid = type;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
ExactValue exact_value_integer_from_string(String const &string) {
|
||||
gb_internal ExactValue exact_value_integer_from_string(String const &string) {
|
||||
ExactValue result = {ExactValue_Integer};
|
||||
bool success;
|
||||
big_int_from_string(&result.value_integer, string, &success);
|
||||
@@ -184,7 +184,7 @@ ExactValue exact_value_integer_from_string(String const &string) {
|
||||
|
||||
|
||||
|
||||
f64 float_from_string(String string) {
|
||||
gb_internal f64 float_from_string(String string) {
|
||||
isize i = 0;
|
||||
u8 *str = string.text;
|
||||
isize len = string.len;
|
||||
@@ -262,7 +262,7 @@ f64 float_from_string(String string) {
|
||||
return sign * (frac ? (value / scale) : (value * scale));
|
||||
}
|
||||
|
||||
ExactValue exact_value_float_from_string(String string) {
|
||||
gb_internal ExactValue exact_value_float_from_string(String string) {
|
||||
if (string.len > 2 && string[0] == '0' && string[1] == 'h') {
|
||||
|
||||
isize digit_count = 0;
|
||||
@@ -298,7 +298,7 @@ ExactValue exact_value_float_from_string(String string) {
|
||||
}
|
||||
|
||||
|
||||
ExactValue exact_value_from_basic_literal(TokenKind kind, String const &string) {
|
||||
gb_internal ExactValue exact_value_from_basic_literal(TokenKind kind, String const &string) {
|
||||
switch (kind) {
|
||||
case Token_String: return exact_value_string(string);
|
||||
case Token_Integer: return exact_value_integer_from_string(string);
|
||||
@@ -330,7 +330,7 @@ ExactValue exact_value_from_basic_literal(TokenKind kind, String const &string)
|
||||
return result;
|
||||
}
|
||||
|
||||
ExactValue exact_value_to_integer(ExactValue v) {
|
||||
gb_internal ExactValue exact_value_to_integer(ExactValue v) {
|
||||
switch (v.kind) {
|
||||
case ExactValue_Bool: {
|
||||
i64 i = 0;
|
||||
@@ -357,7 +357,7 @@ ExactValue exact_value_to_integer(ExactValue v) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ExactValue exact_value_to_float(ExactValue v) {
|
||||
gb_internal ExactValue exact_value_to_float(ExactValue v) {
|
||||
switch (v.kind) {
|
||||
case ExactValue_Integer:
|
||||
return exact_value_float(big_int_to_f64(&v.value_integer));
|
||||
@@ -368,7 +368,7 @@ ExactValue exact_value_to_float(ExactValue v) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ExactValue exact_value_to_complex(ExactValue v) {
|
||||
gb_internal ExactValue exact_value_to_complex(ExactValue v) {
|
||||
switch (v.kind) {
|
||||
case ExactValue_Integer:
|
||||
return exact_value_complex(big_int_to_f64(&v.value_integer), 0);
|
||||
@@ -383,7 +383,7 @@ ExactValue exact_value_to_complex(ExactValue v) {
|
||||
v.value_complex = gb_alloc_item(permanent_allocator(), Complex128);
|
||||
return r;
|
||||
}
|
||||
ExactValue exact_value_to_quaternion(ExactValue v) {
|
||||
gb_internal ExactValue exact_value_to_quaternion(ExactValue v) {
|
||||
switch (v.kind) {
|
||||
case ExactValue_Integer:
|
||||
return exact_value_quaternion(big_int_to_f64(&v.value_integer), 0, 0, 0);
|
||||
@@ -399,7 +399,7 @@ ExactValue exact_value_to_quaternion(ExactValue v) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ExactValue exact_value_real(ExactValue v) {
|
||||
gb_internal ExactValue exact_value_real(ExactValue v) {
|
||||
switch (v.kind) {
|
||||
case ExactValue_Integer:
|
||||
case ExactValue_Float:
|
||||
@@ -413,7 +413,7 @@ ExactValue exact_value_real(ExactValue v) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ExactValue exact_value_imag(ExactValue v) {
|
||||
gb_internal ExactValue exact_value_imag(ExactValue v) {
|
||||
switch (v.kind) {
|
||||
case ExactValue_Integer:
|
||||
case ExactValue_Float:
|
||||
@@ -427,7 +427,7 @@ ExactValue exact_value_imag(ExactValue v) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ExactValue exact_value_jmag(ExactValue v) {
|
||||
gb_internal ExactValue exact_value_jmag(ExactValue v) {
|
||||
switch (v.kind) {
|
||||
case ExactValue_Integer:
|
||||
case ExactValue_Float:
|
||||
@@ -440,7 +440,7 @@ ExactValue exact_value_jmag(ExactValue v) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ExactValue exact_value_kmag(ExactValue v) {
|
||||
gb_internal ExactValue exact_value_kmag(ExactValue v) {
|
||||
switch (v.kind) {
|
||||
case ExactValue_Integer:
|
||||
case ExactValue_Float:
|
||||
@@ -453,7 +453,7 @@ ExactValue exact_value_kmag(ExactValue v) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ExactValue exact_value_make_imag(ExactValue v) {
|
||||
gb_internal ExactValue exact_value_make_imag(ExactValue v) {
|
||||
switch (v.kind) {
|
||||
case ExactValue_Integer:
|
||||
return exact_value_complex(0, exact_value_to_float(v).value_float);
|
||||
@@ -466,7 +466,7 @@ ExactValue exact_value_make_imag(ExactValue v) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ExactValue exact_value_make_jmag(ExactValue v) {
|
||||
gb_internal ExactValue exact_value_make_jmag(ExactValue v) {
|
||||
switch (v.kind) {
|
||||
case ExactValue_Integer:
|
||||
return exact_value_quaternion(0, 0, exact_value_to_float(v).value_float, 0);
|
||||
@@ -479,7 +479,7 @@ ExactValue exact_value_make_jmag(ExactValue v) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ExactValue exact_value_make_kmag(ExactValue v) {
|
||||
gb_internal ExactValue exact_value_make_kmag(ExactValue v) {
|
||||
switch (v.kind) {
|
||||
case ExactValue_Integer:
|
||||
return exact_value_quaternion(0, 0, 0, exact_value_to_float(v).value_float);
|
||||
@@ -492,21 +492,21 @@ ExactValue exact_value_make_kmag(ExactValue v) {
|
||||
return r;
|
||||
}
|
||||
|
||||
i64 exact_value_to_i64(ExactValue v) {
|
||||
gb_internal i64 exact_value_to_i64(ExactValue v) {
|
||||
v = exact_value_to_integer(v);
|
||||
if (v.kind == ExactValue_Integer) {
|
||||
return big_int_to_i64(&v.value_integer);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
u64 exact_value_to_u64(ExactValue v) {
|
||||
gb_internal u64 exact_value_to_u64(ExactValue v) {
|
||||
v = exact_value_to_integer(v);
|
||||
if (v.kind == ExactValue_Integer) {
|
||||
return big_int_to_u64(&v.value_integer);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
f64 exact_value_to_f64(ExactValue v) {
|
||||
gb_internal f64 exact_value_to_f64(ExactValue v) {
|
||||
v = exact_value_to_float(v);
|
||||
if (v.kind == ExactValue_Float) {
|
||||
return v.value_float;
|
||||
@@ -519,7 +519,7 @@ f64 exact_value_to_f64(ExactValue v) {
|
||||
|
||||
|
||||
|
||||
ExactValue exact_unary_operator_value(TokenKind op, ExactValue v, i32 precision, bool is_unsigned) {
|
||||
gb_internal ExactValue exact_unary_operator_value(TokenKind op, ExactValue v, i32 precision, bool is_unsigned) {
|
||||
switch (op) {
|
||||
case Token_Add: {
|
||||
switch (v.kind) {
|
||||
@@ -596,7 +596,7 @@ failure:
|
||||
}
|
||||
|
||||
// NOTE(bill): Make sure things are evaluated in correct order
|
||||
i32 exact_value_order(ExactValue const &v) {
|
||||
gb_internal i32 exact_value_order(ExactValue const &v) {
|
||||
switch (v.kind) {
|
||||
case ExactValue_Invalid:
|
||||
case ExactValue_Compound:
|
||||
@@ -623,7 +623,7 @@ i32 exact_value_order(ExactValue const &v) {
|
||||
}
|
||||
}
|
||||
|
||||
void match_exact_values(ExactValue *x, ExactValue *y) {
|
||||
gb_internal void match_exact_values(ExactValue *x, ExactValue *y) {
|
||||
if (exact_value_order(*y) < exact_value_order(*x)) {
|
||||
match_exact_values(y, x);
|
||||
return;
|
||||
@@ -687,7 +687,7 @@ void match_exact_values(ExactValue *x, ExactValue *y) {
|
||||
}
|
||||
|
||||
// TODO(bill): Allow for pointer arithmetic? Or are pointer slices good enough?
|
||||
ExactValue exact_binary_operator_value(TokenKind op, ExactValue x, ExactValue y) {
|
||||
gb_internal ExactValue exact_binary_operator_value(TokenKind op, ExactValue x, ExactValue y) {
|
||||
match_exact_values(&x, &y);
|
||||
|
||||
switch (x.kind) {
|
||||
@@ -846,32 +846,32 @@ error:; // NOTE(bill): MSVC accepts this??? apparently you cannot declare variab
|
||||
return empty_exact_value;
|
||||
}
|
||||
|
||||
gb_inline ExactValue exact_value_add(ExactValue const &x, ExactValue const &y) {
|
||||
gb_internal gb_inline ExactValue exact_value_add(ExactValue const &x, ExactValue const &y) {
|
||||
return exact_binary_operator_value(Token_Add, x, y);
|
||||
}
|
||||
gb_inline ExactValue exact_value_sub(ExactValue const &x, ExactValue const &y) {
|
||||
gb_internal gb_inline ExactValue exact_value_sub(ExactValue const &x, ExactValue const &y) {
|
||||
return exact_binary_operator_value(Token_Sub, x, y);
|
||||
}
|
||||
gb_inline ExactValue exact_value_mul(ExactValue const &x, ExactValue const &y) {
|
||||
gb_internal gb_inline ExactValue exact_value_mul(ExactValue const &x, ExactValue const &y) {
|
||||
return exact_binary_operator_value(Token_Mul, x, y);
|
||||
}
|
||||
gb_inline ExactValue exact_value_quo(ExactValue const &x, ExactValue const &y) {
|
||||
gb_internal gb_inline ExactValue exact_value_quo(ExactValue const &x, ExactValue const &y) {
|
||||
return exact_binary_operator_value(Token_Quo, x, y);
|
||||
}
|
||||
gb_inline ExactValue exact_value_shift(TokenKind op, ExactValue const &x, ExactValue const &y) {
|
||||
gb_internal gb_inline ExactValue exact_value_shift(TokenKind op, ExactValue const &x, ExactValue const &y) {
|
||||
return exact_binary_operator_value(op, x, y);
|
||||
}
|
||||
|
||||
gb_inline ExactValue exact_value_increment_one(ExactValue const &x) {
|
||||
gb_internal gb_inline ExactValue exact_value_increment_one(ExactValue const &x) {
|
||||
return exact_binary_operator_value(Token_Add, x, exact_value_i64(1));
|
||||
}
|
||||
|
||||
|
||||
i32 cmp_f64(f64 a, f64 b) {
|
||||
gb_internal gb_inline i32 cmp_f64(f64 a, f64 b) {
|
||||
return (a > b) - (a < b);
|
||||
}
|
||||
|
||||
bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y) {
|
||||
gb_internal bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y) {
|
||||
match_exact_values(&x, &y);
|
||||
|
||||
switch (x.kind) {
|
||||
@@ -974,7 +974,7 @@ Entity *strip_entity_wrapping(Entity *e);
|
||||
|
||||
gbString write_expr_to_string(gbString str, Ast *node, bool shorthand);
|
||||
|
||||
gbString write_exact_value_to_string(gbString str, ExactValue const &v, isize string_limit=36) {
|
||||
gb_internal gbString write_exact_value_to_string(gbString str, ExactValue const &v, isize string_limit=36) {
|
||||
switch (v.kind) {
|
||||
case ExactValue_Invalid:
|
||||
return str;
|
||||
@@ -1017,6 +1017,6 @@ gbString write_exact_value_to_string(gbString str, ExactValue const &v, isize st
|
||||
return str;
|
||||
};
|
||||
|
||||
gbString exact_value_to_string(ExactValue const &v, isize string_limit=36) {
|
||||
gb_internal gbString exact_value_to_string(ExactValue const &v, isize string_limit=36) {
|
||||
return write_exact_value_to_string(gb_string_make(heap_allocator(), ""), v, string_limit);
|
||||
}
|
||||
|
||||
42
src/main.cpp
42
src/main.cpp
@@ -8,20 +8,20 @@
|
||||
#include "build_settings.cpp"
|
||||
|
||||
gb_global ThreadPool global_thread_pool;
|
||||
void init_global_thread_pool(void) {
|
||||
gb_internal void init_global_thread_pool(void) {
|
||||
isize thread_count = gb_max(build_context.thread_count, 1);
|
||||
isize worker_count = thread_count-1; // NOTE(bill): The main thread will also be used for work
|
||||
thread_pool_init(&global_thread_pool, permanent_allocator(), worker_count, "ThreadPoolWorker");
|
||||
}
|
||||
bool global_thread_pool_add_task(WorkerTaskProc *proc, void *data) {
|
||||
gb_internal bool global_thread_pool_add_task(WorkerTaskProc *proc, void *data) {
|
||||
return thread_pool_add_task(&global_thread_pool, proc, data);
|
||||
}
|
||||
void global_thread_pool_wait(void) {
|
||||
gb_internal void global_thread_pool_wait(void) {
|
||||
thread_pool_wait(&global_thread_pool);
|
||||
}
|
||||
|
||||
|
||||
void debugf(char const *fmt, ...) {
|
||||
gb_internal void debugf(char const *fmt, ...) {
|
||||
if (build_context.show_debug_messages) {
|
||||
gb_printf_err("[DEBUG] ");
|
||||
va_list va;
|
||||
@@ -62,7 +62,7 @@ gb_global Timings global_timings = {0};
|
||||
#include "bug_report.cpp"
|
||||
|
||||
// NOTE(bill): 'name' is used in debugging and profiling modes
|
||||
i32 system_exec_command_line_app(char const *name, char const *fmt, ...) {
|
||||
gb_internal i32 system_exec_command_line_app(char const *name, char const *fmt, ...) {
|
||||
isize const cmd_cap = 64<<20; // 64 MiB should be more than enough
|
||||
char *cmd_line = gb_alloc_array(gb_heap_allocator(), char, cmd_cap);
|
||||
isize cmd_len = 0;
|
||||
@@ -124,7 +124,7 @@ i32 system_exec_command_line_app(char const *name, char const *fmt, ...) {
|
||||
}
|
||||
|
||||
|
||||
i32 linker_stage(lbGenerator *gen) {
|
||||
gb_internal i32 linker_stage(lbGenerator *gen) {
|
||||
i32 result = 0;
|
||||
Timings *timings = &global_timings;
|
||||
|
||||
@@ -524,7 +524,7 @@ i32 linker_stage(lbGenerator *gen) {
|
||||
return result;
|
||||
}
|
||||
|
||||
Array<String> setup_args(int argc, char const **argv) {
|
||||
gb_internal Array<String> setup_args(int argc, char const **argv) {
|
||||
gbAllocator a = heap_allocator();
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
@@ -553,7 +553,7 @@ Array<String> setup_args(int argc, char const **argv) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void print_usage_line(i32 indent, char const *fmt, ...) {
|
||||
gb_internal void print_usage_line(i32 indent, char const *fmt, ...) {
|
||||
while (indent --> 0) {
|
||||
gb_printf_err("\t");
|
||||
}
|
||||
@@ -564,7 +564,7 @@ void print_usage_line(i32 indent, char const *fmt, ...) {
|
||||
gb_printf_err("\n");
|
||||
}
|
||||
|
||||
void usage(String argv0) {
|
||||
gb_internal void usage(String argv0) {
|
||||
print_usage_line(0, "%.*s is a tool for managing Odin source code", LIT(argv0));
|
||||
print_usage_line(0, "Usage:");
|
||||
print_usage_line(1, "%.*s command [arguments]", LIT(argv0));
|
||||
@@ -687,12 +687,12 @@ struct BuildFlag {
|
||||
};
|
||||
|
||||
|
||||
void add_flag(Array<BuildFlag> *build_flags, BuildFlagKind kind, String name, BuildFlagParamKind param_kind, u32 command_support, bool allow_mulitple=false) {
|
||||
gb_internal void add_flag(Array<BuildFlag> *build_flags, BuildFlagKind kind, String name, BuildFlagParamKind param_kind, u32 command_support, bool allow_mulitple=false) {
|
||||
BuildFlag flag = {kind, name, param_kind, command_support, allow_mulitple};
|
||||
array_add(build_flags, flag);
|
||||
}
|
||||
|
||||
ExactValue build_param_to_exact_value(String name, String param) {
|
||||
gb_internal ExactValue build_param_to_exact_value(String name, String param) {
|
||||
ExactValue value = {};
|
||||
|
||||
/*
|
||||
@@ -747,7 +747,7 @@ ExactValue build_param_to_exact_value(String name, String param) {
|
||||
}
|
||||
|
||||
// Writes a did-you-mean message for formerly deprecated flags.
|
||||
void did_you_mean_flag(String flag) {
|
||||
gb_internal void did_you_mean_flag(String flag) {
|
||||
gbAllocator a = heap_allocator();
|
||||
String name = copy_string(a, flag);
|
||||
defer (gb_free(a, name.text));
|
||||
@@ -760,7 +760,7 @@ void did_you_mean_flag(String flag) {
|
||||
gb_printf_err("Unknown flag: '%.*s'\n", LIT(flag));
|
||||
}
|
||||
|
||||
bool parse_build_flags(Array<String> args) {
|
||||
gb_internal bool parse_build_flags(Array<String> args) {
|
||||
auto build_flags = array_make<BuildFlag>(heap_allocator(), 0, BuildFlag_COUNT);
|
||||
add_flag(&build_flags, BuildFlag_Help, str_lit("help"), BuildFlagParam_None, Command_all);
|
||||
add_flag(&build_flags, BuildFlag_SingleFile, str_lit("file"), BuildFlagParam_None, Command__does_build | Command__does_check);
|
||||
@@ -1651,7 +1651,7 @@ bool parse_build_flags(Array<String> args) {
|
||||
return !bad_flags;
|
||||
}
|
||||
|
||||
void timings_export_all(Timings *t, Checker *c, bool timings_are_finalized = false) {
|
||||
gb_internal void timings_export_all(Timings *t, Checker *c, bool timings_are_finalized = false) {
|
||||
GB_ASSERT((!(build_context.export_timings_format == TimingsExportUnspecified) && build_context.export_timings_file.len > 0));
|
||||
|
||||
/*
|
||||
@@ -1749,7 +1749,7 @@ void timings_export_all(Timings *t, Checker *c, bool timings_are_finalized = fal
|
||||
gb_printf("Done.\n");
|
||||
}
|
||||
|
||||
void show_timings(Checker *c, Timings *t) {
|
||||
gb_internal void show_timings(Checker *c, Timings *t) {
|
||||
Parser *p = c->parser;
|
||||
isize lines = p->total_line_count;
|
||||
isize tokens = p->total_token_count;
|
||||
@@ -1878,7 +1878,7 @@ void show_timings(Checker *c, Timings *t) {
|
||||
}
|
||||
}
|
||||
|
||||
void remove_temp_files(lbGenerator *gen) {
|
||||
gb_internal void remove_temp_files(lbGenerator *gen) {
|
||||
if (build_context.keep_temp_files) return;
|
||||
|
||||
TIME_SECTION("remove keep temp files");
|
||||
@@ -1902,7 +1902,7 @@ void remove_temp_files(lbGenerator *gen) {
|
||||
}
|
||||
|
||||
|
||||
void print_show_help(String const arg0, String const &command) {
|
||||
gb_internal void print_show_help(String const arg0, String const &command) {
|
||||
print_usage_line(0, "%.*s is a tool for managing Odin source code", LIT(arg0));
|
||||
print_usage_line(0, "Usage:");
|
||||
print_usage_line(1, "%.*s %.*s [arguments]", LIT(arg0), LIT(command));
|
||||
@@ -2248,7 +2248,7 @@ void print_show_help(String const arg0, String const &command) {
|
||||
}
|
||||
}
|
||||
|
||||
void print_show_unused(Checker *c) {
|
||||
gb_internal void print_show_unused(Checker *c) {
|
||||
CheckerInfo *info = &c->info;
|
||||
|
||||
auto unused = array_make<Entity *>(permanent_allocator(), 0, info->entities.count);
|
||||
@@ -2322,7 +2322,7 @@ void print_show_unused(Checker *c) {
|
||||
print_usage_line(0, "");
|
||||
}
|
||||
|
||||
bool check_env(void) {
|
||||
gb_internal bool check_env(void) {
|
||||
gbAllocator a = heap_allocator();
|
||||
char const *odin_root = gb_get_env("ODIN_ROOT", a);
|
||||
defer (gb_free(a, cast(void *)odin_root));
|
||||
@@ -2348,7 +2348,7 @@ struct StripSemicolonFile {
|
||||
i64 written;
|
||||
};
|
||||
|
||||
gbFileError write_file_with_stripped_tokens(gbFile *f, AstFile *file, i64 *written_) {
|
||||
gb_internal gbFileError write_file_with_stripped_tokens(gbFile *f, AstFile *file, i64 *written_) {
|
||||
i64 written = 0;
|
||||
gbFileError err = gbFileError_None;
|
||||
u8 const *file_data = file->tokenizer.start;
|
||||
@@ -2388,7 +2388,7 @@ gbFileError write_file_with_stripped_tokens(gbFile *f, AstFile *file, i64 *writt
|
||||
return err;
|
||||
}
|
||||
|
||||
int strip_semicolons(Parser *parser) {
|
||||
gb_internal int strip_semicolons(Parser *parser) {
|
||||
isize file_count = 0;
|
||||
for_array(i, parser->packages) {
|
||||
AstPackage *pkg = parser->packages[i];
|
||||
|
||||
@@ -58,40 +58,40 @@ struct Find_Result {
|
||||
String vs_library_path;
|
||||
};
|
||||
|
||||
String mc_wstring_to_string(wchar_t const *str) {
|
||||
gb_internal String mc_wstring_to_string(wchar_t const *str) {
|
||||
return string16_to_string(mc_allocator, make_string16_c(str));
|
||||
}
|
||||
|
||||
String16 mc_string_to_wstring(String str) {
|
||||
gb_internal String16 mc_string_to_wstring(String str) {
|
||||
return string_to_string16(mc_allocator, str);
|
||||
}
|
||||
|
||||
String mc_concat(String a, String b) {
|
||||
gb_internal String mc_concat(String a, String b) {
|
||||
return concatenate_strings(mc_allocator, a, b);
|
||||
}
|
||||
|
||||
String mc_concat(String a, String b, String c) {
|
||||
gb_internal String mc_concat(String a, String b, String c) {
|
||||
return concatenate3_strings(mc_allocator, a, b, c);
|
||||
}
|
||||
|
||||
String mc_concat(String a, String b, String c, String d) {
|
||||
gb_internal String mc_concat(String a, String b, String c, String d) {
|
||||
return concatenate4_strings(mc_allocator, a, b, c, d);
|
||||
}
|
||||
|
||||
String mc_get_env(String key) {
|
||||
gb_internal String mc_get_env(String key) {
|
||||
char const * value = gb_get_env((char const *)key.text, mc_allocator);
|
||||
return make_string_c(value);
|
||||
}
|
||||
|
||||
void mc_free(String str) {
|
||||
gb_internal void mc_free(String str) {
|
||||
if (str.len) gb_free(mc_allocator, str.text);
|
||||
}
|
||||
|
||||
void mc_free(String16 str) {
|
||||
gb_internal void mc_free(String16 str) {
|
||||
if (str.len) gb_free(mc_allocator, str.text);
|
||||
}
|
||||
|
||||
void mc_free_all() {
|
||||
gb_internal void mc_free_all() {
|
||||
gb_free_all(mc_allocator);
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ typedef struct _MC_Find_Data {
|
||||
} MC_Find_Data;
|
||||
|
||||
|
||||
HANDLE mc_find_first(String wildcard, MC_Find_Data *find_data) {
|
||||
gb_internal HANDLE mc_find_first(String wildcard, MC_Find_Data *find_data) {
|
||||
WIN32_FIND_DATAW _find_data;
|
||||
|
||||
String16 wildcard_wide = mc_string_to_wstring(wildcard);
|
||||
@@ -115,7 +115,7 @@ HANDLE mc_find_first(String wildcard, MC_Find_Data *find_data) {
|
||||
return handle;
|
||||
}
|
||||
|
||||
bool mc_find_next(HANDLE handle, MC_Find_Data *find_data) {
|
||||
gb_internal bool mc_find_next(HANDLE handle, MC_Find_Data *find_data) {
|
||||
WIN32_FIND_DATAW _find_data;
|
||||
bool success = !!FindNextFileW(handle, &_find_data);
|
||||
|
||||
@@ -124,7 +124,7 @@ bool mc_find_next(HANDLE handle, MC_Find_Data *find_data) {
|
||||
return success;
|
||||
}
|
||||
|
||||
void mc_find_close(HANDLE handle) {
|
||||
gb_internal void mc_find_close(HANDLE handle) {
|
||||
FindClose(handle);
|
||||
}
|
||||
|
||||
@@ -216,7 +216,7 @@ struct Version_Data {
|
||||
};
|
||||
|
||||
typedef void (*MC_Visit_Proc)(String short_name, String full_name, Version_Data *data);
|
||||
bool mc_visit_files(String dir_name, Version_Data *data, MC_Visit_Proc proc) {
|
||||
gb_internal bool mc_visit_files(String dir_name, Version_Data *data, MC_Visit_Proc proc) {
|
||||
|
||||
// Visit everything in one folder (non-recursively). If it's a directory
|
||||
// that doesn't start with ".", call the visit proc on it. The visit proc
|
||||
@@ -246,7 +246,7 @@ bool mc_visit_files(String dir_name, Version_Data *data, MC_Visit_Proc proc) {
|
||||
return true;
|
||||
}
|
||||
|
||||
String find_windows_kit_root(HKEY key, String const version) {
|
||||
gb_internal String find_windows_kit_root(HKEY key, String const version) {
|
||||
// Given a key to an already opened registry entry,
|
||||
// get the value stored under the 'version' subkey.
|
||||
// If that's not the right terminology, hey, I never do registry stuff.
|
||||
@@ -275,7 +275,7 @@ String find_windows_kit_root(HKEY key, String const version) {
|
||||
return value;
|
||||
}
|
||||
|
||||
void win10_best(String short_name, String full_name, Version_Data *data) {
|
||||
gb_internal void win10_best(String short_name, String full_name, Version_Data *data) {
|
||||
// Find the Windows 10 subdirectory with the highest version number.
|
||||
|
||||
int i0, i1, i2, i3;
|
||||
@@ -307,7 +307,7 @@ void win10_best(String short_name, String full_name, Version_Data *data) {
|
||||
}
|
||||
}
|
||||
|
||||
void find_windows_kit_paths(Find_Result *result) {
|
||||
gb_internal void find_windows_kit_paths(Find_Result *result) {
|
||||
bool sdk_found = false;
|
||||
|
||||
HKEY main_key;
|
||||
@@ -355,7 +355,7 @@ void find_windows_kit_paths(Find_Result *result) {
|
||||
}
|
||||
}
|
||||
|
||||
bool find_visual_studio_by_fighting_through_microsoft_craziness(Find_Result *result) {
|
||||
gb_internal bool find_visual_studio_by_fighting_through_microsoft_craziness(Find_Result *result) {
|
||||
// The name of this procedure is kind of cryptic. Its purpose is
|
||||
// to fight through Microsoft craziness. The things that the fine
|
||||
// Visual Studio team want you to do, JUST TO FIND A SINGLE FOLDER
|
||||
@@ -519,7 +519,7 @@ bool find_visual_studio_by_fighting_through_microsoft_craziness(Find_Result *res
|
||||
|
||||
// NOTE(WalterPlinge): Environment variables can help to find Visual C++ and WinSDK paths for both
|
||||
// official and portable installations (like mmozeiko's portable msvc script).
|
||||
void find_windows_kit_paths_from_env_vars(Find_Result *result) {
|
||||
gb_internal void find_windows_kit_paths_from_env_vars(Find_Result *result) {
|
||||
if (build_context.metrics.arch != TargetArch_amd64 && build_context.metrics.arch != TargetArch_i386) {
|
||||
return;
|
||||
}
|
||||
@@ -669,7 +669,7 @@ void find_windows_kit_paths_from_env_vars(Find_Result *result) {
|
||||
// NOTE(WalterPlinge): Environment variables can help to find Visual C++ and WinSDK paths for both
|
||||
// official and portable installations (like mmozeiko's portable msvc script). This will only use
|
||||
// the first paths it finds, and won't overwrite any values that `result` already has.
|
||||
void find_visual_studio_paths_from_env_vars(Find_Result *result) {
|
||||
gb_internal void find_visual_studio_paths_from_env_vars(Find_Result *result) {
|
||||
if (build_context.metrics.arch != TargetArch_amd64 && build_context.metrics.arch != TargetArch_i386) {
|
||||
return;
|
||||
}
|
||||
@@ -756,7 +756,7 @@ void find_visual_studio_paths_from_env_vars(Find_Result *result) {
|
||||
}
|
||||
}
|
||||
|
||||
Find_Result find_visual_studio_and_windows_sdk() {
|
||||
gb_internal Find_Result find_visual_studio_and_windows_sdk() {
|
||||
Find_Result r = {};
|
||||
find_windows_kit_paths(&r);
|
||||
find_visual_studio_by_fighting_through_microsoft_craziness(&r);
|
||||
|
||||
460
src/parser.cpp
460
src/parser.cpp
File diff suppressed because it is too large
Load Diff
@@ -258,7 +258,7 @@ enum ProcCallingConvention : i32 {
|
||||
ProcCC_ForeignBlockDefault = -1,
|
||||
};
|
||||
|
||||
char const *proc_calling_convention_strings[ProcCC_MAX] = {
|
||||
gb_global char const *proc_calling_convention_strings[ProcCC_MAX] = {
|
||||
"",
|
||||
"odin",
|
||||
"contextless",
|
||||
@@ -272,7 +272,7 @@ char const *proc_calling_convention_strings[ProcCC_MAX] = {
|
||||
"sysv",
|
||||
};
|
||||
|
||||
ProcCallingConvention default_calling_convention(void) {
|
||||
gb_internal ProcCallingConvention default_calling_convention(void) {
|
||||
return ProcCC_Odin;
|
||||
}
|
||||
|
||||
@@ -332,7 +332,7 @@ enum InlineAsmDialectKind : u8 {
|
||||
InlineAsmDialect_COUNT,
|
||||
};
|
||||
|
||||
char const *inline_asm_dialect_strings[InlineAsmDialect_COUNT] = {
|
||||
gb_global char const *inline_asm_dialect_strings[InlineAsmDialect_COUNT] = {
|
||||
"",
|
||||
"att",
|
||||
"intel",
|
||||
@@ -729,7 +729,7 @@ enum AstKind : u16 {
|
||||
Ast_COUNT,
|
||||
};
|
||||
|
||||
String const ast_strings[] = {
|
||||
gb_global String const ast_strings[] = {
|
||||
{cast(u8 *)"invalid node", gb_size_of("invalid node")},
|
||||
#define AST_KIND(_kind_name_, name, ...) {cast(u8 *)name, gb_size_of(name)-1},
|
||||
AST_KINDS
|
||||
@@ -742,7 +742,7 @@ String const ast_strings[] = {
|
||||
#undef AST_KIND
|
||||
|
||||
|
||||
isize const ast_variant_sizes[] = {
|
||||
gb_global isize const ast_variant_sizes[] = {
|
||||
0,
|
||||
#define AST_KIND(_kind_name_, name, ...) gb_size_of(GB_JOIN2(Ast, _kind_name_)),
|
||||
AST_KINDS
|
||||
@@ -793,33 +793,33 @@ struct Ast {
|
||||
#endif
|
||||
|
||||
|
||||
gb_inline bool is_ast_expr(Ast *node) {
|
||||
gb_internal gb_inline bool is_ast_expr(Ast *node) {
|
||||
return gb_is_between(node->kind, Ast__ExprBegin+1, Ast__ExprEnd-1);
|
||||
}
|
||||
gb_inline bool is_ast_stmt(Ast *node) {
|
||||
gb_internal gb_inline bool is_ast_stmt(Ast *node) {
|
||||
return gb_is_between(node->kind, Ast__StmtBegin+1, Ast__StmtEnd-1);
|
||||
}
|
||||
gb_inline bool is_ast_complex_stmt(Ast *node) {
|
||||
gb_internal gb_inline bool is_ast_complex_stmt(Ast *node) {
|
||||
return gb_is_between(node->kind, Ast__ComplexStmtBegin+1, Ast__ComplexStmtEnd-1);
|
||||
}
|
||||
gb_inline bool is_ast_decl(Ast *node) {
|
||||
gb_internal gb_inline bool is_ast_decl(Ast *node) {
|
||||
return gb_is_between(node->kind, Ast__DeclBegin+1, Ast__DeclEnd-1);
|
||||
}
|
||||
gb_inline bool is_ast_type(Ast *node) {
|
||||
gb_internal gb_inline bool is_ast_type(Ast *node) {
|
||||
return gb_is_between(node->kind, Ast__TypeBegin+1, Ast__TypeEnd-1);
|
||||
}
|
||||
gb_inline bool is_ast_when_stmt(Ast *node) {
|
||||
gb_internal gb_inline bool is_ast_when_stmt(Ast *node) {
|
||||
return node->kind == Ast_WhenStmt;
|
||||
}
|
||||
|
||||
gb_global gb_thread_local Arena global_thread_local_ast_arena = {};
|
||||
|
||||
gbAllocator ast_allocator(AstFile *f) {
|
||||
gb_internal gbAllocator ast_allocator(AstFile *f) {
|
||||
Arena *arena = &global_thread_local_ast_arena;
|
||||
return arena_allocator(arena);
|
||||
}
|
||||
|
||||
Ast *alloc_ast_node(AstFile *f, AstKind kind);
|
||||
gb_internal Ast *alloc_ast_node(AstFile *f, AstKind kind);
|
||||
|
||||
gbString expr_to_string(Ast *expression);
|
||||
bool allow_field_separator(AstFile *f);
|
||||
gb_internal gbString expr_to_string(Ast *expression);
|
||||
gb_internal bool allow_field_separator(AstFile *f);
|
||||
@@ -1,4 +1,4 @@
|
||||
Token ast_token(Ast *node) {
|
||||
gb_internal Token ast_token(Ast *node) {
|
||||
switch (node->kind) {
|
||||
case Ast_Ident: return node->Ident.token;
|
||||
case Ast_Implicit: return node->Implicit;
|
||||
@@ -360,6 +360,6 @@ Token ast_end_token(Ast *node) {
|
||||
return empty_token;
|
||||
}
|
||||
|
||||
TokenPos ast_end_pos(Ast *node) {
|
||||
gb_internal TokenPos ast_end_pos(Ast *node) {
|
||||
return token_pos_end(ast_end_token(node));
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ struct PriorityQueue {
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
bool priority_queue_shift_down(PriorityQueue<T> *pq, isize i0, isize n) {
|
||||
gb_internal bool priority_queue_shift_down(PriorityQueue<T> *pq, isize i0, isize n) {
|
||||
// O(n log n)
|
||||
isize i = i0;
|
||||
isize j, j1, j2;
|
||||
@@ -29,7 +29,7 @@ bool priority_queue_shift_down(PriorityQueue<T> *pq, isize i0, isize n) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void priority_queue_shift_up(PriorityQueue<T> *pq, isize j) {
|
||||
gb_internal void priority_queue_shift_up(PriorityQueue<T> *pq, isize j) {
|
||||
while (0 <= j && j < pq->queue.count) {
|
||||
isize i = (j-1)/2;
|
||||
if (i == j || pq->cmp(&pq->queue[0], j, i) >= 0) {
|
||||
@@ -43,20 +43,20 @@ void priority_queue_shift_up(PriorityQueue<T> *pq, isize j) {
|
||||
// NOTE(bill): When an element at index `i0` has changed its value, this will fix the
|
||||
// the heap ordering. This using a basic "heapsort" with shift up and a shift down parts.
|
||||
template <typename T>
|
||||
void priority_queue_fix(PriorityQueue<T> *pq, isize i) {
|
||||
gb_internal void priority_queue_fix(PriorityQueue<T> *pq, isize i) {
|
||||
if (!priority_queue_shift_down(pq, i, pq->queue.count)) {
|
||||
priority_queue_shift_up(pq, i);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void priority_queue_push(PriorityQueue<T> *pq, T const &value) {
|
||||
gb_internal void priority_queue_push(PriorityQueue<T> *pq, T const &value) {
|
||||
array_add(&pq->queue, value);
|
||||
priority_queue_shift_up(pq, pq->queue.count-1);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T priority_queue_pop(PriorityQueue<T> *pq) {
|
||||
gb_internal T priority_queue_pop(PriorityQueue<T> *pq) {
|
||||
GB_ASSERT(pq->queue.count > 0);
|
||||
|
||||
isize n = pq->queue.count - 1;
|
||||
@@ -67,7 +67,7 @@ T priority_queue_pop(PriorityQueue<T> *pq) {
|
||||
|
||||
|
||||
template <typename T>
|
||||
T priority_queue_remove(PriorityQueue<T> *pq, isize i) {
|
||||
gb_internal T priority_queue_remove(PriorityQueue<T> *pq, isize i) {
|
||||
GB_ASSERT(0 <= i && i < pq->queue.count);
|
||||
isize n = pq->queue.count - 1;
|
||||
if (n != i) {
|
||||
@@ -80,7 +80,7 @@ T priority_queue_remove(PriorityQueue<T> *pq, isize i) {
|
||||
|
||||
|
||||
template <typename T>
|
||||
PriorityQueue<T> priority_queue_create(Array<T> queue,
|
||||
gb_internal PriorityQueue<T> priority_queue_create(Array<T> queue,
|
||||
int (* cmp) (T *q, isize i, isize j),
|
||||
void (* swap)(T *q, isize i, isize j)) {
|
||||
PriorityQueue<T> pq = {};
|
||||
|
||||
@@ -26,7 +26,7 @@ struct PtrMap {
|
||||
};
|
||||
|
||||
|
||||
u32 ptr_map_hash_key(uintptr key) {
|
||||
gb_internal gb_inline u32 ptr_map_hash_key(uintptr key) {
|
||||
#if defined(GB_ARCH_64_BIT)
|
||||
key = (~key) + (key << 21);
|
||||
key = key ^ (key >> 24);
|
||||
@@ -41,35 +41,35 @@ u32 ptr_map_hash_key(uintptr key) {
|
||||
return (word >> 22u) ^ word;
|
||||
#endif
|
||||
}
|
||||
u32 ptr_map_hash_key(void const *key) {
|
||||
gb_internal gb_inline u32 ptr_map_hash_key(void const *key) {
|
||||
return ptr_map_hash_key((uintptr)key);
|
||||
}
|
||||
|
||||
|
||||
template <typename K, typename V> void map_init (PtrMap<K, V> *h, gbAllocator a, isize capacity = 16);
|
||||
template <typename K, typename V> void map_destroy (PtrMap<K, V> *h);
|
||||
template <typename K, typename V> V * map_get (PtrMap<K, V> *h, K key);
|
||||
template <typename K, typename V> void map_set (PtrMap<K, V> *h, K key, V const &value);
|
||||
template <typename K, typename V> void map_remove (PtrMap<K, V> *h, K key);
|
||||
template <typename K, typename V> void map_clear (PtrMap<K, V> *h);
|
||||
template <typename K, typename V> void map_grow (PtrMap<K, V> *h);
|
||||
template <typename K, typename V> void map_rehash (PtrMap<K, V> *h, isize new_count);
|
||||
template <typename K, typename V> void map_reserve (PtrMap<K, V> *h, isize cap);
|
||||
template <typename K, typename V> gb_internal void map_init (PtrMap<K, V> *h, gbAllocator a, isize capacity = 16);
|
||||
template <typename K, typename V> gb_internal void map_destroy (PtrMap<K, V> *h);
|
||||
template <typename K, typename V> gb_internal V * map_get (PtrMap<K, V> *h, K key);
|
||||
template <typename K, typename V> gb_internal void map_set (PtrMap<K, V> *h, K key, V const &value);
|
||||
template <typename K, typename V> gb_internal void map_remove (PtrMap<K, V> *h, K key);
|
||||
template <typename K, typename V> gb_internal void map_clear (PtrMap<K, V> *h);
|
||||
template <typename K, typename V> gb_internal void map_grow (PtrMap<K, V> *h);
|
||||
template <typename K, typename V> gb_internal void map_rehash (PtrMap<K, V> *h, isize new_count);
|
||||
template <typename K, typename V> gb_internal void map_reserve (PtrMap<K, V> *h, isize cap);
|
||||
|
||||
#if PTR_MAP_ENABLE_MULTI_MAP
|
||||
// Mutlivalued map procedure
|
||||
template <typename K, typename V> PtrMapEntry<K, V> * multi_map_find_first(PtrMap<K, V> *h, K key);
|
||||
template <typename K, typename V> PtrMapEntry<K, V> * multi_map_find_next (PtrMap<K, V> *h, PtrMapEntry<K, V> *e);
|
||||
template <typename K, typename V> gb_internal PtrMapEntry<K, V> * multi_map_find_first(PtrMap<K, V> *h, K key);
|
||||
template <typename K, typename V> gb_internal PtrMapEntry<K, V> * multi_map_find_next (PtrMap<K, V> *h, PtrMapEntry<K, V> *e);
|
||||
|
||||
template <typename K, typename V> isize multi_map_count (PtrMap<K, V> *h, K key);
|
||||
template <typename K, typename V> void multi_map_get_all (PtrMap<K, V> *h, K key, V *items);
|
||||
template <typename K, typename V> void multi_map_insert (PtrMap<K, V> *h, K key, V const &value);
|
||||
template <typename K, typename V> void multi_map_remove (PtrMap<K, V> *h, K key, PtrMapEntry<K, V> *e);
|
||||
template <typename K, typename V> void multi_map_remove_all(PtrMap<K, V> *h, K key);
|
||||
template <typename K, typename V> gb_internal isize multi_map_count (PtrMap<K, V> *h, K key);
|
||||
template <typename K, typename V> gb_internal void multi_map_get_all (PtrMap<K, V> *h, K key, V *items);
|
||||
template <typename K, typename V> gb_internal void multi_map_insert (PtrMap<K, V> *h, K key, V const &value);
|
||||
template <typename K, typename V> gb_internal void multi_map_remove (PtrMap<K, V> *h, K key, PtrMapEntry<K, V> *e);
|
||||
template <typename K, typename V> gb_internal void multi_map_remove_all(PtrMap<K, V> *h, K key);
|
||||
#endif
|
||||
|
||||
template <typename K, typename V>
|
||||
gb_inline void map_init(PtrMap<K, V> *h, gbAllocator a, isize capacity) {
|
||||
gb_internal gb_inline void map_init(PtrMap<K, V> *h, gbAllocator a, isize capacity) {
|
||||
capacity = next_pow2_isize(capacity);
|
||||
slice_init(&h->hashes, a, capacity);
|
||||
array_init(&h->entries, a, 0, capacity);
|
||||
@@ -79,7 +79,7 @@ gb_inline void map_init(PtrMap<K, V> *h, gbAllocator a, isize capacity) {
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
gb_inline void map_destroy(PtrMap<K, V> *h) {
|
||||
gb_internal gb_inline void map_destroy(PtrMap<K, V> *h) {
|
||||
slice_free(&h->hashes, h->entries.allocator);
|
||||
array_free(&h->entries);
|
||||
}
|
||||
@@ -137,13 +137,13 @@ gb_internal b32 map__full(PtrMap<K, V> *h) {
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
gb_inline void map_grow(PtrMap<K, V> *h) {
|
||||
gb_internal gb_inline void map_grow(PtrMap<K, V> *h) {
|
||||
isize new_count = gb_max(h->hashes.count<<1, 16);
|
||||
map_rehash(h, new_count);
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
void map_reset_entries(PtrMap<K, V> *h) {
|
||||
gb_internal void map_reset_entries(PtrMap<K, V> *h) {
|
||||
for (isize i = 0; i < h->hashes.count; i++) {
|
||||
h->hashes.data[i] = MAP_SENTINEL;
|
||||
}
|
||||
@@ -161,7 +161,7 @@ void map_reset_entries(PtrMap<K, V> *h) {
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
void map_reserve(PtrMap<K, V> *h, isize cap) {
|
||||
gb_internal void map_reserve(PtrMap<K, V> *h, isize cap) {
|
||||
array_reserve(&h->entries, cap);
|
||||
if (h->entries.count*2 < h->hashes.count) {
|
||||
return;
|
||||
@@ -172,12 +172,12 @@ void map_reserve(PtrMap<K, V> *h, isize cap) {
|
||||
|
||||
|
||||
template <typename K, typename V>
|
||||
void map_rehash(PtrMap<K, V> *h, isize new_count) {
|
||||
gb_internal void map_rehash(PtrMap<K, V> *h, isize new_count) {
|
||||
map_reserve(h, new_count);
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
V *map_get(PtrMap<K, V> *h, K key) {
|
||||
gb_internal V *map_get(PtrMap<K, V> *h, K key) {
|
||||
MapIndex index = map__find(h, key).entry_index;
|
||||
if (index != MAP_SENTINEL) {
|
||||
return &h->entries.data[index].value;
|
||||
@@ -186,14 +186,14 @@ V *map_get(PtrMap<K, V> *h, K key) {
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
V &map_must_get(PtrMap<K, V> *h, K key) {
|
||||
gb_internal V &map_must_get(PtrMap<K, V> *h, K key) {
|
||||
MapIndex index = map__find(h, key).entry_index;
|
||||
GB_ASSERT(index != MAP_SENTINEL);
|
||||
return h->entries.data[index].value;
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
void map_set(PtrMap<K, V> *h, K key, V const &value) {
|
||||
gb_internal void map_set(PtrMap<K, V> *h, K key, V const &value) {
|
||||
MapIndex index;
|
||||
MapFindResult fr;
|
||||
if (h->hashes.count == 0) {
|
||||
@@ -219,7 +219,7 @@ void map_set(PtrMap<K, V> *h, K key, V const &value) {
|
||||
|
||||
|
||||
template <typename K, typename V>
|
||||
void map__erase(PtrMap<K, V> *h, MapFindResult const &fr) {
|
||||
gb_internal void map__erase(PtrMap<K, V> *h, MapFindResult const &fr) {
|
||||
MapFindResult last;
|
||||
if (fr.entry_prev == MAP_SENTINEL) {
|
||||
h->hashes.data[fr.hash_index] = h->entries.data[fr.entry_index].next;
|
||||
@@ -242,7 +242,7 @@ void map__erase(PtrMap<K, V> *h, MapFindResult const &fr) {
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
void map_remove(PtrMap<K, V> *h, K key) {
|
||||
gb_internal void map_remove(PtrMap<K, V> *h, K key) {
|
||||
MapFindResult fr = map__find(h, key);
|
||||
if (fr.entry_index != MAP_SENTINEL) {
|
||||
map__erase(h, fr);
|
||||
@@ -250,7 +250,7 @@ void map_remove(PtrMap<K, V> *h, K key) {
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
gb_inline void map_clear(PtrMap<K, V> *h) {
|
||||
gb_internal gb_inline void map_clear(PtrMap<K, V> *h) {
|
||||
array_clear(&h->entries);
|
||||
for (isize i = 0; i < h->hashes.count; i++) {
|
||||
h->hashes.data[i] = MAP_SENTINEL;
|
||||
@@ -260,7 +260,7 @@ gb_inline void map_clear(PtrMap<K, V> *h) {
|
||||
|
||||
#if PTR_MAP_ENABLE_MULTI_MAP
|
||||
template <typename K, typename V>
|
||||
PtrMapEntry<K, V> *multi_map_find_first(PtrMap<K, V> *h, K key) {
|
||||
gb_internal PtrMapEntry<K, V> *multi_map_find_first(PtrMap<K, V> *h, K key) {
|
||||
MapIndex i = map__find(h, key).entry_index;
|
||||
if (i == MAP_SENTINEL) {
|
||||
return nullptr;
|
||||
@@ -269,7 +269,7 @@ PtrMapEntry<K, V> *multi_map_find_first(PtrMap<K, V> *h, K key) {
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
PtrMapEntry<K, V> *multi_map_find_next(PtrMap<K, V> *h, PtrMapEntry<K, V> *e) {
|
||||
gb_internal PtrMapEntry<K, V> *multi_map_find_next(PtrMap<K, V> *h, PtrMapEntry<K, V> *e) {
|
||||
MapIndex i = e->next;
|
||||
while (i != MAP_SENTINEL) {
|
||||
if (h->entries.data[i].key == e->key) {
|
||||
@@ -281,7 +281,7 @@ PtrMapEntry<K, V> *multi_map_find_next(PtrMap<K, V> *h, PtrMapEntry<K, V> *e) {
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
isize multi_map_count(PtrMap<K, V> *h, K key) {
|
||||
gb_internal isize multi_map_count(PtrMap<K, V> *h, K key) {
|
||||
isize count = 0;
|
||||
PtrMapEntry<K, V> *e = multi_map_find_first(h, key);
|
||||
while (e != nullptr) {
|
||||
@@ -292,7 +292,7 @@ isize multi_map_count(PtrMap<K, V> *h, K key) {
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
void multi_map_get_all(PtrMap<K, V> *h, K key, V *items) {
|
||||
gb_internal void multi_map_get_all(PtrMap<K, V> *h, K key, V *items) {
|
||||
isize i = 0;
|
||||
PtrMapEntry<K, V> *e = multi_map_find_first(h, key);
|
||||
while (e != nullptr) {
|
||||
@@ -302,7 +302,7 @@ void multi_map_get_all(PtrMap<K, V> *h, K key, V *items) {
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
void multi_map_insert(PtrMap<K, V> *h, K key, V const &value) {
|
||||
gb_internal void multi_map_insert(PtrMap<K, V> *h, K key, V const &value) {
|
||||
MapFindResult fr;
|
||||
MapIndex i;
|
||||
if (h->hashes.count == 0) {
|
||||
@@ -325,7 +325,7 @@ void multi_map_insert(PtrMap<K, V> *h, K key, V const &value) {
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
void multi_map_remove(PtrMap<K, V> *h, K key, PtrMapEntry<K, V> *e) {
|
||||
gb_internal void multi_map_remove(PtrMap<K, V> *h, K key, PtrMapEntry<K, V> *e) {
|
||||
MapFindResult fr = map__find_from_entry(h, e);
|
||||
if (fr.entry_index != MAP_SENTINEL) {
|
||||
map__erase(h, fr);
|
||||
@@ -333,7 +333,7 @@ void multi_map_remove(PtrMap<K, V> *h, K key, PtrMapEntry<K, V> *e) {
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
void multi_map_remove_all(PtrMap<K, V> *h, K key) {
|
||||
gb_internal void multi_map_remove_all(PtrMap<K, V> *h, K key) {
|
||||
while (map_get(h, key) != nullptr) {
|
||||
map_remove(h, key);
|
||||
}
|
||||
@@ -342,21 +342,21 @@ void multi_map_remove_all(PtrMap<K, V> *h, K key) {
|
||||
|
||||
|
||||
template <typename K, typename V>
|
||||
PtrMapEntry<K, V> *begin(PtrMap<K, V> &m) {
|
||||
gb_internal PtrMapEntry<K, V> *begin(PtrMap<K, V> &m) {
|
||||
return m.entries.data;
|
||||
}
|
||||
template <typename K, typename V>
|
||||
PtrMapEntry<K, V> const *begin(PtrMap<K, V> const &m) {
|
||||
gb_internal PtrMapEntry<K, V> const *begin(PtrMap<K, V> const &m) {
|
||||
return m.entries.data;
|
||||
}
|
||||
|
||||
|
||||
template <typename K, typename V>
|
||||
PtrMapEntry<K, V> *end(PtrMap<K, V> &m) {
|
||||
gb_internal PtrMapEntry<K, V> *end(PtrMap<K, V> &m) {
|
||||
return m.entries.data + m.entries.count;
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
PtrMapEntry<K, V> const *end(PtrMap<K, V> const &m) {
|
||||
gb_internal PtrMapEntry<K, V> const *end(PtrMap<K, V> const &m) {
|
||||
return m.entries.data + m.entries.count;
|
||||
}
|
||||
|
||||
@@ -10,20 +10,20 @@ struct PtrSet {
|
||||
Array<PtrSetEntry<T>> entries;
|
||||
};
|
||||
|
||||
template <typename T> void ptr_set_init (PtrSet<T> *s, gbAllocator a, isize capacity = 16);
|
||||
template <typename T> void ptr_set_destroy(PtrSet<T> *s);
|
||||
template <typename T> T ptr_set_add (PtrSet<T> *s, T ptr);
|
||||
template <typename T> bool ptr_set_update (PtrSet<T> *s, T ptr); // returns true if it previously existed
|
||||
template <typename T> bool ptr_set_exists (PtrSet<T> *s, T ptr);
|
||||
template <typename T> void ptr_set_remove (PtrSet<T> *s, T ptr);
|
||||
template <typename T> void ptr_set_clear (PtrSet<T> *s);
|
||||
template <typename T> void ptr_set_grow (PtrSet<T> *s);
|
||||
template <typename T> void ptr_set_rehash (PtrSet<T> *s, isize new_count);
|
||||
template <typename T> void ptr_set_reserve(PtrSet<T> *h, isize cap);
|
||||
template <typename T> gb_internal void ptr_set_init (PtrSet<T> *s, gbAllocator a, isize capacity = 16);
|
||||
template <typename T> gb_internal void ptr_set_destroy(PtrSet<T> *s);
|
||||
template <typename T> gb_internal T ptr_set_add (PtrSet<T> *s, T ptr);
|
||||
template <typename T> gb_internal bool ptr_set_update (PtrSet<T> *s, T ptr); // returns true if it previously existed
|
||||
template <typename T> gb_internal bool ptr_set_exists (PtrSet<T> *s, T ptr);
|
||||
template <typename T> gb_internal void ptr_set_remove (PtrSet<T> *s, T ptr);
|
||||
template <typename T> gb_internal void ptr_set_clear (PtrSet<T> *s);
|
||||
template <typename T> gb_internal void ptr_set_grow (PtrSet<T> *s);
|
||||
template <typename T> gb_internal void ptr_set_rehash (PtrSet<T> *s, isize new_count);
|
||||
template <typename T> gb_internal void ptr_set_reserve(PtrSet<T> *h, isize cap);
|
||||
|
||||
|
||||
template <typename T>
|
||||
void ptr_set_init(PtrSet<T> *s, gbAllocator a, isize capacity) {
|
||||
gb_internal void ptr_set_init(PtrSet<T> *s, gbAllocator a, isize capacity) {
|
||||
if (capacity != 0) {
|
||||
capacity = next_pow2_isize(gb_max(16, capacity));
|
||||
}
|
||||
@@ -36,7 +36,7 @@ void ptr_set_init(PtrSet<T> *s, gbAllocator a, isize capacity) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void ptr_set_destroy(PtrSet<T> *s) {
|
||||
gb_internal void ptr_set_destroy(PtrSet<T> *s) {
|
||||
slice_free(&s->hashes, s->entries.allocator);
|
||||
array_free(&s->entries);
|
||||
}
|
||||
@@ -93,13 +93,13 @@ gb_internal bool ptr_set__full(PtrSet<T> *s) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
gb_inline void ptr_set_grow(PtrSet<T> *s) {
|
||||
gb_internal gb_inline void ptr_set_grow(PtrSet<T> *s) {
|
||||
isize new_count = gb_max(s->hashes.count<<1, 16);
|
||||
ptr_set_rehash(s, new_count);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void ptr_set_reset_entries(PtrSet<T> *s) {
|
||||
gb_internal void ptr_set_reset_entries(PtrSet<T> *s) {
|
||||
for (isize i = 0; i < s->hashes.count; i++) {
|
||||
s->hashes.data[i] = MAP_SENTINEL;
|
||||
}
|
||||
@@ -117,7 +117,7 @@ void ptr_set_reset_entries(PtrSet<T> *s) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void ptr_set_reserve(PtrSet<T> *s, isize cap) {
|
||||
gb_internal void ptr_set_reserve(PtrSet<T> *s, isize cap) {
|
||||
array_reserve(&s->entries, cap);
|
||||
if (s->entries.count*2 < s->hashes.count) {
|
||||
return;
|
||||
@@ -128,18 +128,18 @@ void ptr_set_reserve(PtrSet<T> *s, isize cap) {
|
||||
|
||||
|
||||
template <typename T>
|
||||
void ptr_set_rehash(PtrSet<T> *s, isize new_count) {
|
||||
gb_internal void ptr_set_rehash(PtrSet<T> *s, isize new_count) {
|
||||
ptr_set_reserve(s, new_count);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
gb_inline bool ptr_set_exists(PtrSet<T> *s, T ptr) {
|
||||
gb_internal gb_inline bool ptr_set_exists(PtrSet<T> *s, T ptr) {
|
||||
isize index = ptr_set__find(s, ptr).entry_index;
|
||||
return index != MAP_SENTINEL;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
gb_inline isize ptr_entry_index(PtrSet<T> *s, T ptr) {
|
||||
gb_internal gb_inline isize ptr_entry_index(PtrSet<T> *s, T ptr) {
|
||||
isize index = ptr_set__find(s, ptr).entry_index;
|
||||
if (index != MAP_SENTINEL) {
|
||||
return index;
|
||||
@@ -149,7 +149,7 @@ gb_inline isize ptr_entry_index(PtrSet<T> *s, T ptr) {
|
||||
|
||||
// Returns true if it already exists
|
||||
template <typename T>
|
||||
T ptr_set_add(PtrSet<T> *s, T ptr) {
|
||||
gb_internal T ptr_set_add(PtrSet<T> *s, T ptr) {
|
||||
MapIndex index;
|
||||
MapFindResult fr;
|
||||
if (s->hashes.count == 0) {
|
||||
@@ -171,7 +171,7 @@ T ptr_set_add(PtrSet<T> *s, T ptr) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool ptr_set_update(PtrSet<T> *s, T ptr) { // returns true if it previously existsed
|
||||
gb_internal bool ptr_set_update(PtrSet<T> *s, T ptr) { // returns true if it previously existsed
|
||||
bool exists = false;
|
||||
MapIndex index;
|
||||
MapFindResult fr;
|
||||
@@ -198,7 +198,7 @@ bool ptr_set_update(PtrSet<T> *s, T ptr) { // returns true if it previously exis
|
||||
|
||||
|
||||
template <typename T>
|
||||
void ptr_set__erase(PtrSet<T> *s, MapFindResult fr) {
|
||||
gb_internal void ptr_set__erase(PtrSet<T> *s, MapFindResult fr) {
|
||||
MapFindResult last;
|
||||
if (fr.entry_prev == MAP_SENTINEL) {
|
||||
s->hashes.data[fr.hash_index] = s->entries.data[fr.entry_index].next;
|
||||
@@ -219,7 +219,7 @@ void ptr_set__erase(PtrSet<T> *s, MapFindResult fr) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void ptr_set_remove(PtrSet<T> *s, T ptr) {
|
||||
gb_internal void ptr_set_remove(PtrSet<T> *s, T ptr) {
|
||||
MapFindResult fr = ptr_set__find(s, ptr);
|
||||
if (fr.entry_index != MAP_SENTINEL) {
|
||||
ptr_set__erase(s, fr);
|
||||
@@ -227,7 +227,7 @@ void ptr_set_remove(PtrSet<T> *s, T ptr) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
gb_inline void ptr_set_clear(PtrSet<T> *s) {
|
||||
gb_internal gb_inline void ptr_set_clear(PtrSet<T> *s) {
|
||||
array_clear(&s->entries);
|
||||
for (isize i = 0; i < s->hashes.count; i++) {
|
||||
s->hashes.data[i] = MAP_SENTINEL;
|
||||
@@ -236,21 +236,21 @@ gb_inline void ptr_set_clear(PtrSet<T> *s) {
|
||||
|
||||
|
||||
template <typename T>
|
||||
PtrSetEntry<T> *begin(PtrSet<T> &m) {
|
||||
gb_internal PtrSetEntry<T> *begin(PtrSet<T> &m) {
|
||||
return m.entries.data;
|
||||
}
|
||||
template <typename T>
|
||||
PtrSetEntry<T> const *begin(PtrSet<T> const &m) {
|
||||
gb_internal PtrSetEntry<T> const *begin(PtrSet<T> const &m) {
|
||||
return m.entries.data;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
PtrSetEntry<T> *end(PtrSet<T> &m) {
|
||||
gb_internal PtrSetEntry<T> *end(PtrSet<T> &m) {
|
||||
return m.entries.data + m.entries.count;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
PtrSetEntry<T> const *end(PtrSet<T> const &m) {
|
||||
gb_internal PtrSetEntry<T> const *end(PtrSet<T> const &m) {
|
||||
return m.entries.data + m.entries.count;
|
||||
}
|
||||
@@ -23,7 +23,7 @@ struct MPMCQueue {
|
||||
|
||||
|
||||
|
||||
void mpmc_internal_init_indices(MPMCQueueAtomicIdx *indices, i32 offset, i32 size) {
|
||||
gb_internal void mpmc_internal_init_indices(MPMCQueueAtomicIdx *indices, i32 offset, i32 size) {
|
||||
GB_ASSERT(offset % 8 == 0);
|
||||
GB_ASSERT(size % 8 == 0);
|
||||
|
||||
@@ -43,7 +43,7 @@ void mpmc_internal_init_indices(MPMCQueueAtomicIdx *indices, i32 offset, i32 siz
|
||||
|
||||
|
||||
template <typename T>
|
||||
void mpmc_init(MPMCQueue<T> *q, gbAllocator a, isize size_i) {
|
||||
gb_internal void mpmc_init(MPMCQueue<T> *q, gbAllocator a, isize size_i) {
|
||||
if (size_i < 8) {
|
||||
size_i = 8;
|
||||
}
|
||||
@@ -64,7 +64,7 @@ void mpmc_init(MPMCQueue<T> *q, gbAllocator a, isize size_i) {
|
||||
|
||||
|
||||
template <typename T>
|
||||
void mpmc_destroy(MPMCQueue<T> *q) {
|
||||
gb_internal void mpmc_destroy(MPMCQueue<T> *q) {
|
||||
mutex_destroy(&q->mutex);
|
||||
gb_free(q->allocator, q->nodes);
|
||||
gb_free(q->allocator, q->indices);
|
||||
@@ -72,7 +72,7 @@ void mpmc_destroy(MPMCQueue<T> *q) {
|
||||
|
||||
|
||||
template <typename T>
|
||||
bool mpmc_internal_grow(MPMCQueue<T> *q) {
|
||||
gb_internal bool mpmc_internal_grow(MPMCQueue<T> *q) {
|
||||
mutex_lock(&q->mutex);
|
||||
i32 old_size = q->mask+1;
|
||||
i32 new_size = old_size*2;
|
||||
@@ -95,7 +95,7 @@ bool mpmc_internal_grow(MPMCQueue<T> *q) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
i32 mpmc_enqueue(MPMCQueue<T> *q, T const &data) {
|
||||
gb_internal i32 mpmc_enqueue(MPMCQueue<T> *q, T const &data) {
|
||||
GB_ASSERT(q->mask != 0);
|
||||
|
||||
i32 head_idx = q->head_idx.load(std::memory_order_relaxed);
|
||||
@@ -125,7 +125,7 @@ i32 mpmc_enqueue(MPMCQueue<T> *q, T const &data) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool mpmc_dequeue(MPMCQueue<T> *q, T *data_) {
|
||||
gb_internal bool mpmc_dequeue(MPMCQueue<T> *q, T *data_) {
|
||||
if (q->mask == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -10,17 +10,17 @@ struct RangeCache {
|
||||
};
|
||||
|
||||
|
||||
RangeCache range_cache_make(gbAllocator a) {
|
||||
gb_internal RangeCache range_cache_make(gbAllocator a) {
|
||||
RangeCache cache = {};
|
||||
array_init(&cache.ranges, a);
|
||||
return cache;
|
||||
}
|
||||
|
||||
void range_cache_destroy(RangeCache *c) {
|
||||
gb_internal void range_cache_destroy(RangeCache *c) {
|
||||
array_free(&c->ranges);
|
||||
}
|
||||
|
||||
bool range_cache_add_index(RangeCache *c, i64 index) {
|
||||
gb_internal bool range_cache_add_index(RangeCache *c, i64 index) {
|
||||
for_array(i, c->ranges) {
|
||||
RangeValue v = c->ranges[i];
|
||||
if (v.lo <= index && index <= v.hi) {
|
||||
@@ -33,7 +33,7 @@ bool range_cache_add_index(RangeCache *c, i64 index) {
|
||||
}
|
||||
|
||||
|
||||
bool range_cache_add_range(RangeCache *c, i64 lo, i64 hi) {
|
||||
gb_internal bool range_cache_add_range(RangeCache *c, i64 lo, i64 hi) {
|
||||
GB_ASSERT(lo <= hi);
|
||||
for_array(i, c->ranges) {
|
||||
RangeValue v = c->ranges[i];
|
||||
@@ -59,7 +59,7 @@ bool range_cache_add_range(RangeCache *c, i64 lo, i64 hi) {
|
||||
}
|
||||
|
||||
|
||||
bool range_cache_index_exists(RangeCache *c, i64 index) {
|
||||
gb_internal bool range_cache_index_exists(RangeCache *c, i64 index) {
|
||||
for_array(i, c->ranges) {
|
||||
RangeValue v = c->ranges[i];
|
||||
if (v.lo <= index && index <= v.hi) {
|
||||
|
||||
118
src/string.cpp
118
src/string.cpp
@@ -1,6 +1,6 @@
|
||||
gb_global BlockingMutex string_buffer_mutex = {};
|
||||
|
||||
void init_string_buffer_memory(void) {
|
||||
gb_internal void init_string_buffer_memory(void) {
|
||||
mutex_init(&string_buffer_mutex);
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ struct String16 {
|
||||
};
|
||||
|
||||
|
||||
gb_inline String make_string(u8 const *text, isize len) {
|
||||
gb_internal gb_inline String make_string(u8 const *text, isize len) {
|
||||
String s;
|
||||
s.text = cast(u8 *)text;
|
||||
if (len < 0) {
|
||||
@@ -47,14 +47,14 @@ gb_inline String make_string(u8 const *text, isize len) {
|
||||
}
|
||||
|
||||
|
||||
gb_inline String16 make_string16(wchar_t const *text, isize len) {
|
||||
gb_internal gb_inline String16 make_string16(wchar_t const *text, isize len) {
|
||||
String16 s;
|
||||
s.text = cast(wchar_t *)text;
|
||||
s.len = len;
|
||||
return s;
|
||||
}
|
||||
|
||||
isize string16_len(wchar_t const *s) {
|
||||
gb_internal isize string16_len(wchar_t const *s) {
|
||||
if (s == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
@@ -66,15 +66,15 @@ isize string16_len(wchar_t const *s) {
|
||||
}
|
||||
|
||||
|
||||
gb_inline String make_string_c(char const *text) {
|
||||
gb_internal gb_inline String make_string_c(char const *text) {
|
||||
return make_string(cast(u8 *)cast(void *)text, gb_strlen(text));
|
||||
}
|
||||
|
||||
gb_inline String16 make_string16_c(wchar_t const *text) {
|
||||
gb_internal gb_inline String16 make_string16_c(wchar_t const *text) {
|
||||
return make_string16(text, string16_len(text));
|
||||
}
|
||||
|
||||
String substring(String const &s, isize lo, isize hi) {
|
||||
gb_internal String substring(String const &s, isize lo, isize hi) {
|
||||
isize max = s.len;
|
||||
GB_ASSERT_MSG(lo <= hi && hi <= max, "%td..%td..%td", lo, hi, max);
|
||||
|
||||
@@ -82,14 +82,14 @@ String substring(String const &s, isize lo, isize hi) {
|
||||
}
|
||||
|
||||
|
||||
char *alloc_cstring(gbAllocator a, String s) {
|
||||
gb_internal char *alloc_cstring(gbAllocator a, String s) {
|
||||
char *c_str = gb_alloc_array(a, char, s.len+1);
|
||||
gb_memmove(c_str, s.text, s.len);
|
||||
c_str[s.len] = '\0';
|
||||
return c_str;
|
||||
}
|
||||
|
||||
char *cstring_duplicate(gbAllocator a, char const *s) {
|
||||
gb_internal char *cstring_duplicate(gbAllocator a, char const *s) {
|
||||
isize len = gb_strlen(s);
|
||||
char *c_str = gb_alloc_array(a, char, len+1);
|
||||
gb_memmove(c_str, s, len);
|
||||
@@ -99,7 +99,7 @@ char *cstring_duplicate(gbAllocator a, char const *s) {
|
||||
|
||||
|
||||
|
||||
gb_inline bool str_eq_ignore_case(String const &a, String const &b) {
|
||||
gb_internal gb_inline bool str_eq_ignore_case(String const &a, String const &b) {
|
||||
if (a.len == b.len) {
|
||||
for (isize i = 0; i < a.len; i++) {
|
||||
char x = cast(char)a[i];
|
||||
@@ -113,13 +113,13 @@ gb_inline bool str_eq_ignore_case(String const &a, String const &b) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void string_to_lower(String *s) {
|
||||
gb_internal void string_to_lower(String *s) {
|
||||
for (isize i = 0; i < s->len; i++) {
|
||||
s->text[i] = gb_char_to_lower(s->text[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int string_compare(String const &x, String const &y) {
|
||||
gb_internal int string_compare(String const &x, String const &y) {
|
||||
if (x.len != y.len || x.text != y.text) {
|
||||
isize n, fast, offset, curr_block;
|
||||
isize *la, *lb;
|
||||
@@ -157,7 +157,7 @@ int string_compare(String const &x, String const &y) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
isize string_index_byte(String const &s, u8 x) {
|
||||
gb_internal isize string_index_byte(String const &s, u8 x) {
|
||||
for (isize i = 0; i < s.len; i++) {
|
||||
if (s.text[i] == x) {
|
||||
return i;
|
||||
@@ -166,37 +166,37 @@ isize string_index_byte(String const &s, u8 x) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
GB_COMPARE_PROC(string_cmp_proc) {
|
||||
gb_internal GB_COMPARE_PROC(string_cmp_proc) {
|
||||
String x = *(String *)a;
|
||||
String y = *(String *)b;
|
||||
return string_compare(x, y);
|
||||
}
|
||||
|
||||
gb_inline bool str_eq(String const &a, String const &b) {
|
||||
gb_internal gb_inline bool str_eq(String const &a, String const &b) {
|
||||
if (a.len != b.len) return false;
|
||||
return memcmp(a.text, b.text, a.len) == 0;
|
||||
}
|
||||
gb_inline bool str_ne(String const &a, String const &b) { return !str_eq(a, b); }
|
||||
gb_inline bool str_lt(String const &a, String const &b) { return string_compare(a, b) < 0; }
|
||||
gb_inline bool str_gt(String const &a, String const &b) { return string_compare(a, b) > 0; }
|
||||
gb_inline bool str_le(String const &a, String const &b) { return string_compare(a, b) <= 0; }
|
||||
gb_inline bool str_ge(String const &a, String const &b) { return string_compare(a, b) >= 0; }
|
||||
gb_internal gb_inline bool str_ne(String const &a, String const &b) { return !str_eq(a, b); }
|
||||
gb_internal gb_inline bool str_lt(String const &a, String const &b) { return string_compare(a, b) < 0; }
|
||||
gb_internal gb_inline bool str_gt(String const &a, String const &b) { return string_compare(a, b) > 0; }
|
||||
gb_internal gb_inline bool str_le(String const &a, String const &b) { return string_compare(a, b) <= 0; }
|
||||
gb_internal gb_inline bool str_ge(String const &a, String const &b) { return string_compare(a, b) >= 0; }
|
||||
|
||||
gb_inline bool operator == (String const &a, String const &b) { return str_eq(a, b); }
|
||||
gb_inline bool operator != (String const &a, String const &b) { return str_ne(a, b); }
|
||||
gb_inline bool operator < (String const &a, String const &b) { return str_lt(a, b); }
|
||||
gb_inline bool operator > (String const &a, String const &b) { return str_gt(a, b); }
|
||||
gb_inline bool operator <= (String const &a, String const &b) { return str_le(a, b); }
|
||||
gb_inline bool operator >= (String const &a, String const &b) { return str_ge(a, b); }
|
||||
gb_internal gb_inline bool operator == (String const &a, String const &b) { return str_eq(a, b); }
|
||||
gb_internal gb_inline bool operator != (String const &a, String const &b) { return str_ne(a, b); }
|
||||
gb_internal gb_inline bool operator < (String const &a, String const &b) { return str_lt(a, b); }
|
||||
gb_internal gb_inline bool operator > (String const &a, String const &b) { return str_gt(a, b); }
|
||||
gb_internal gb_inline bool operator <= (String const &a, String const &b) { return str_le(a, b); }
|
||||
gb_internal gb_inline bool operator >= (String const &a, String const &b) { return str_ge(a, b); }
|
||||
|
||||
template <isize N> bool operator == (String const &a, char const (&b)[N]) { return str_eq(a, make_string(cast(u8 *)b, N-1)); }
|
||||
template <isize N> bool operator != (String const &a, char const (&b)[N]) { return str_ne(a, make_string(cast(u8 *)b, N-1)); }
|
||||
template <isize N> bool operator < (String const &a, char const (&b)[N]) { return str_lt(a, make_string(cast(u8 *)b, N-1)); }
|
||||
template <isize N> bool operator > (String const &a, char const (&b)[N]) { return str_gt(a, make_string(cast(u8 *)b, N-1)); }
|
||||
template <isize N> bool operator <= (String const &a, char const (&b)[N]) { return str_le(a, make_string(cast(u8 *)b, N-1)); }
|
||||
template <isize N> bool operator >= (String const &a, char const (&b)[N]) { return str_ge(a, make_string(cast(u8 *)b, N-1)); }
|
||||
template <isize N> gb_internal bool operator == (String const &a, char const (&b)[N]) { return str_eq(a, make_string(cast(u8 *)b, N-1)); }
|
||||
template <isize N> gb_internal bool operator != (String const &a, char const (&b)[N]) { return str_ne(a, make_string(cast(u8 *)b, N-1)); }
|
||||
template <isize N> gb_internal bool operator < (String const &a, char const (&b)[N]) { return str_lt(a, make_string(cast(u8 *)b, N-1)); }
|
||||
template <isize N> gb_internal bool operator > (String const &a, char const (&b)[N]) { return str_gt(a, make_string(cast(u8 *)b, N-1)); }
|
||||
template <isize N> gb_internal bool operator <= (String const &a, char const (&b)[N]) { return str_le(a, make_string(cast(u8 *)b, N-1)); }
|
||||
template <isize N> gb_internal bool operator >= (String const &a, char const (&b)[N]) { return str_ge(a, make_string(cast(u8 *)b, N-1)); }
|
||||
|
||||
gb_inline bool string_starts_with(String const &s, String const &prefix) {
|
||||
gb_internal gb_inline bool string_starts_with(String const &s, String const &prefix) {
|
||||
if (prefix.len > s.len) {
|
||||
return false;
|
||||
}
|
||||
@@ -204,7 +204,7 @@ gb_inline bool string_starts_with(String const &s, String const &prefix) {
|
||||
return substring(s, 0, prefix.len) == prefix;
|
||||
}
|
||||
|
||||
gb_inline bool string_ends_with(String const &s, String const &suffix) {
|
||||
gb_internal gb_inline bool string_ends_with(String const &s, String const &suffix) {
|
||||
if (suffix.len > s.len) {
|
||||
return false;
|
||||
}
|
||||
@@ -212,7 +212,7 @@ gb_inline bool string_ends_with(String const &s, String const &suffix) {
|
||||
return substring(s, s.len-suffix.len, s.len) == suffix;
|
||||
}
|
||||
|
||||
gb_inline bool string_starts_with(String const &s, u8 prefix) {
|
||||
gb_internal gb_inline bool string_starts_with(String const &s, u8 prefix) {
|
||||
if (1 > s.len) {
|
||||
return false;
|
||||
}
|
||||
@@ -221,7 +221,7 @@ gb_inline bool string_starts_with(String const &s, u8 prefix) {
|
||||
}
|
||||
|
||||
|
||||
gb_inline bool string_ends_with(String const &s, u8 suffix) {
|
||||
gb_internal gb_inline bool string_ends_with(String const &s, u8 suffix) {
|
||||
if (1 > s.len) {
|
||||
return false;
|
||||
}
|
||||
@@ -231,7 +231,7 @@ gb_inline bool string_ends_with(String const &s, u8 suffix) {
|
||||
|
||||
|
||||
|
||||
gb_inline String string_trim_starts_with(String const &s, String const &prefix) {
|
||||
gb_internal gb_inline String string_trim_starts_with(String const &s, String const &prefix) {
|
||||
if (string_starts_with(s, prefix)) {
|
||||
return substring(s, prefix.len, s.len);
|
||||
}
|
||||
@@ -239,7 +239,7 @@ gb_inline String string_trim_starts_with(String const &s, String const &prefix)
|
||||
}
|
||||
|
||||
|
||||
gb_inline isize string_extension_position(String const &str) {
|
||||
gb_internal gb_inline isize string_extension_position(String const &str) {
|
||||
isize dot_pos = -1;
|
||||
isize i = str.len;
|
||||
while (i --> 0) {
|
||||
@@ -254,7 +254,7 @@ gb_inline isize string_extension_position(String const &str) {
|
||||
return dot_pos;
|
||||
}
|
||||
|
||||
String path_extension(String const &str, bool include_dot = true) {
|
||||
gb_internal String path_extension(String const &str, bool include_dot = true) {
|
||||
isize pos = string_extension_position(str);
|
||||
if (pos < 0) {
|
||||
return make_string(nullptr, 0);
|
||||
@@ -262,7 +262,7 @@ String path_extension(String const &str, bool include_dot = true) {
|
||||
return substring(str, include_dot ? pos : pos + 1, str.len);
|
||||
}
|
||||
|
||||
String string_trim_whitespace(String str) {
|
||||
gb_internal String string_trim_whitespace(String str) {
|
||||
while (str.len > 0 && rune_is_whitespace(str[str.len-1])) {
|
||||
str.len--;
|
||||
}
|
||||
@@ -279,7 +279,7 @@ String string_trim_whitespace(String str) {
|
||||
return str;
|
||||
}
|
||||
|
||||
bool string_contains_char(String const &s, u8 c) {
|
||||
gb_internal bool string_contains_char(String const &s, u8 c) {
|
||||
isize i;
|
||||
for (i = 0; i < s.len; i++) {
|
||||
if (s[i] == c)
|
||||
@@ -288,7 +288,7 @@ bool string_contains_char(String const &s, u8 c) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String filename_from_path(String s) {
|
||||
gb_internal String filename_from_path(String s) {
|
||||
isize i = string_extension_position(s);
|
||||
if (i >= 0) {
|
||||
s = substring(s, 0, i);
|
||||
@@ -307,7 +307,7 @@ String filename_from_path(String s) {
|
||||
return make_string(nullptr, 0);
|
||||
}
|
||||
|
||||
String concatenate_strings(gbAllocator a, String const &x, String const &y) {
|
||||
gb_internal String concatenate_strings(gbAllocator a, String const &x, String const &y) {
|
||||
isize len = x.len+y.len;
|
||||
u8 *data = gb_alloc_array(a, u8, len+1);
|
||||
gb_memmove(data, x.text, x.len);
|
||||
@@ -315,7 +315,7 @@ String concatenate_strings(gbAllocator a, String const &x, String const &y) {
|
||||
data[len] = 0;
|
||||
return make_string(data, len);
|
||||
}
|
||||
String concatenate3_strings(gbAllocator a, String const &x, String const &y, String const &z) {
|
||||
gb_internal String concatenate3_strings(gbAllocator a, String const &x, String const &y, String const &z) {
|
||||
isize len = x.len+y.len+z.len;
|
||||
u8 *data = gb_alloc_array(a, u8, len+1);
|
||||
gb_memmove(data, x.text, x.len);
|
||||
@@ -324,7 +324,7 @@ String concatenate3_strings(gbAllocator a, String const &x, String const &y, Str
|
||||
data[len] = 0;
|
||||
return make_string(data, len);
|
||||
}
|
||||
String concatenate4_strings(gbAllocator a, String const &x, String const &y, String const &z, String const &w) {
|
||||
gb_internal String concatenate4_strings(gbAllocator a, String const &x, String const &y, String const &z, String const &w) {
|
||||
isize len = x.len+y.len+z.len+w.len;
|
||||
u8 *data = gb_alloc_array(a, u8, len+1);
|
||||
gb_memmove(data, x.text, x.len);
|
||||
@@ -335,7 +335,7 @@ String concatenate4_strings(gbAllocator a, String const &x, String const &y, Str
|
||||
return make_string(data, len);
|
||||
}
|
||||
|
||||
String string_join_and_quote(gbAllocator a, Array<String> strings) {
|
||||
gb_internal String string_join_and_quote(gbAllocator a, Array<String> strings) {
|
||||
if (!strings.count) {
|
||||
return make_string(nullptr, 0);
|
||||
}
|
||||
@@ -356,7 +356,7 @@ String string_join_and_quote(gbAllocator a, Array<String> strings) {
|
||||
return make_string(cast(u8 *) s, gb_string_length(s));
|
||||
}
|
||||
|
||||
String copy_string(gbAllocator a, String const &s) {
|
||||
gb_internal String copy_string(gbAllocator a, String const &s) {
|
||||
u8 *data = gb_alloc_array(a, u8, s.len+1);
|
||||
gb_memmove(data, s.text, s.len);
|
||||
data[s.len] = 0;
|
||||
@@ -367,17 +367,17 @@ String copy_string(gbAllocator a, String const &s) {
|
||||
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
int convert_multibyte_to_widechar(char const *multibyte_input, int input_length, wchar_t *output, int output_size) {
|
||||
gb_internal int convert_multibyte_to_widechar(char const *multibyte_input, int input_length, wchar_t *output, int output_size) {
|
||||
return MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, multibyte_input, input_length, output, output_size);
|
||||
}
|
||||
int convert_widechar_to_multibyte(wchar_t const *widechar_input, int input_length, char *output, int output_size) {
|
||||
gb_internal int convert_widechar_to_multibyte(wchar_t const *widechar_input, int input_length, char *output, int output_size) {
|
||||
return WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, widechar_input, input_length, output, output_size, nullptr, nullptr);
|
||||
}
|
||||
#elif defined(GB_SYSTEM_UNIX) || defined(GB_SYSTEM_OSX)
|
||||
|
||||
#include <iconv.h>
|
||||
|
||||
int convert_multibyte_to_widechar(char const *multibyte_input, usize input_length, wchar_t *output, usize output_size) {
|
||||
gb_internal int convert_multibyte_to_widechar(char const *multibyte_input, usize input_length, wchar_t *output, usize output_size) {
|
||||
iconv_t conv = iconv_open("WCHAR_T", "UTF-8");
|
||||
size_t result = iconv(conv, cast(char **)&multibyte_input, &input_length, cast(char **)&output, &output_size);
|
||||
iconv_close(conv);
|
||||
@@ -385,7 +385,7 @@ String copy_string(gbAllocator a, String const &s) {
|
||||
return cast(int)result;
|
||||
}
|
||||
|
||||
int convert_widechar_to_multibyte(wchar_t const *widechar_input, usize input_length, char* output, usize output_size) {
|
||||
gb_internal int convert_widechar_to_multibyte(wchar_t const *widechar_input, usize input_length, char* output, usize output_size) {
|
||||
iconv_t conv = iconv_open("UTF-8", "WCHAR_T");
|
||||
size_t result = iconv(conv, cast(char**) &widechar_input, &input_length, cast(char **)&output, &output_size);
|
||||
iconv_close(conv);
|
||||
@@ -400,7 +400,7 @@ String copy_string(gbAllocator a, String const &s) {
|
||||
|
||||
|
||||
// TODO(bill): Make this non-windows specific
|
||||
String16 string_to_string16(gbAllocator a, String s) {
|
||||
gb_internal String16 string_to_string16(gbAllocator a, String s) {
|
||||
int len, len1;
|
||||
wchar_t *text;
|
||||
|
||||
@@ -426,7 +426,7 @@ String16 string_to_string16(gbAllocator a, String s) {
|
||||
}
|
||||
|
||||
|
||||
String string16_to_string(gbAllocator a, String16 s) {
|
||||
gb_internal String string16_to_string(gbAllocator a, String16 s) {
|
||||
int len, len1;
|
||||
u8 *text;
|
||||
|
||||
@@ -458,7 +458,7 @@ String string16_to_string(gbAllocator a, String16 s) {
|
||||
|
||||
|
||||
|
||||
bool is_printable(Rune r) {
|
||||
gb_internal bool is_printable(Rune r) {
|
||||
if (r <= 0xff) {
|
||||
if (0x20 <= r && r <= 0x7e) {
|
||||
return true;
|
||||
@@ -473,7 +473,7 @@ bool is_printable(Rune r) {
|
||||
|
||||
gb_global char const lower_hex[] = "0123456789abcdef";
|
||||
|
||||
String quote_to_ascii(gbAllocator a, String str, u8 quote='"') {
|
||||
gb_internal String quote_to_ascii(gbAllocator a, String str, u8 quote='"') {
|
||||
u8 *s = str.text;
|
||||
isize n = str.len;
|
||||
auto buf = array_make<u8>(a, 0, n);
|
||||
@@ -548,7 +548,7 @@ String quote_to_ascii(gbAllocator a, String str, u8 quote='"') {
|
||||
|
||||
|
||||
|
||||
bool unquote_char(String s, u8 quote, Rune *rune, bool *multiple_bytes, String *tail_string) {
|
||||
gb_internal bool unquote_char(String s, u8 quote, Rune *rune, bool *multiple_bytes, String *tail_string) {
|
||||
u8 c;
|
||||
|
||||
if (s[0] == quote &&
|
||||
@@ -657,7 +657,7 @@ bool unquote_char(String s, u8 quote, Rune *rune, bool *multiple_bytes, String *
|
||||
}
|
||||
|
||||
|
||||
String strip_carriage_return(gbAllocator a, String s) {
|
||||
gb_internal String strip_carriage_return(gbAllocator a, String s) {
|
||||
isize buf_len = s.len;
|
||||
u8 *buf = gb_alloc_array(a, u8, buf_len);
|
||||
isize i = 0;
|
||||
@@ -675,7 +675,7 @@ String strip_carriage_return(gbAllocator a, String s) {
|
||||
// 0 == failure
|
||||
// 1 == original memory
|
||||
// 2 == new allocation
|
||||
i32 unquote_string(gbAllocator a, String *s_, u8 quote=0, bool has_carriage_return=false) {
|
||||
gb_internal i32 unquote_string(gbAllocator a, String *s_, u8 quote=0, bool has_carriage_return=false) {
|
||||
String s = *s_;
|
||||
isize n = s.len;
|
||||
if (quote == 0) {
|
||||
@@ -761,7 +761,7 @@ i32 unquote_string(gbAllocator a, String *s_, u8 quote=0, bool has_carriage_retu
|
||||
|
||||
|
||||
|
||||
bool string_is_valid_identifier(String str) {
|
||||
gb_internal bool string_is_valid_identifier(String str) {
|
||||
if (str.len <= 0) return false;
|
||||
|
||||
isize rune_count = 0;
|
||||
|
||||
@@ -3,7 +3,7 @@ struct StringHashKey {
|
||||
String string;
|
||||
};
|
||||
|
||||
gb_inline StringHashKey string_hash_string(String const &s) {
|
||||
gb_internal gb_inline StringHashKey string_hash_string(String const &s) {
|
||||
StringHashKey hash_key = {};
|
||||
hash_key.hash = fnv32a(s.text, s.len);
|
||||
hash_key.string = s;
|
||||
@@ -11,15 +11,15 @@ gb_inline StringHashKey string_hash_string(String const &s) {
|
||||
}
|
||||
|
||||
|
||||
bool string_hash_key_equal(StringHashKey const &a, StringHashKey const &b) {
|
||||
gb_internal gb_inline bool string_hash_key_equal(StringHashKey const &a, StringHashKey const &b) {
|
||||
if (a.hash == b.hash) {
|
||||
// NOTE(bill): If two string's hashes collide, compare the strings themselves
|
||||
return a.string == b.string;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool operator==(StringHashKey const &a, StringHashKey const &b) { return string_hash_key_equal(a, b); }
|
||||
bool operator!=(StringHashKey const &a, StringHashKey const &b) { return !string_hash_key_equal(a, b); }
|
||||
gb_internal bool operator==(StringHashKey const &a, StringHashKey const &b) { return string_hash_key_equal(a, b); }
|
||||
gb_internal bool operator!=(StringHashKey const &a, StringHashKey const &b) { return !string_hash_key_equal(a, b); }
|
||||
|
||||
template <typename T>
|
||||
struct StringMapEntry {
|
||||
@@ -37,29 +37,29 @@ struct StringMap {
|
||||
};
|
||||
|
||||
|
||||
template <typename T> void string_map_init (StringMap<T> *h, gbAllocator a, isize capacity = 16);
|
||||
template <typename T> void string_map_destroy (StringMap<T> *h);
|
||||
template <typename T> gb_internal void string_map_init (StringMap<T> *h, gbAllocator a, isize capacity = 16);
|
||||
template <typename T> gb_internal void string_map_destroy (StringMap<T> *h);
|
||||
|
||||
template <typename T> T * string_map_get (StringMap<T> *h, char const *key);
|
||||
template <typename T> T * string_map_get (StringMap<T> *h, String const &key);
|
||||
template <typename T> T * string_map_get (StringMap<T> *h, StringHashKey const &key);
|
||||
template <typename T> gb_internal T * string_map_get (StringMap<T> *h, char const *key);
|
||||
template <typename T> gb_internal T * string_map_get (StringMap<T> *h, String const &key);
|
||||
template <typename T> gb_internal T * string_map_get (StringMap<T> *h, StringHashKey const &key);
|
||||
|
||||
template <typename T> T & string_map_must_get (StringMap<T> *h, char const *key);
|
||||
template <typename T> T & string_map_must_get (StringMap<T> *h, String const &key);
|
||||
template <typename T> T & string_map_must_get (StringMap<T> *h, StringHashKey const &key);
|
||||
template <typename T> gb_internal T & string_map_must_get (StringMap<T> *h, char const *key);
|
||||
template <typename T> gb_internal T & string_map_must_get (StringMap<T> *h, String const &key);
|
||||
template <typename T> gb_internal T & string_map_must_get (StringMap<T> *h, StringHashKey const &key);
|
||||
|
||||
template <typename T> void string_map_set (StringMap<T> *h, StringHashKey const &key, T const &value);
|
||||
template <typename T> void string_map_set (StringMap<T> *h, String const &key, T const &value);
|
||||
template <typename T> void string_map_set (StringMap<T> *h, char const *key, T const &value);
|
||||
template <typename T> gb_internal void string_map_set (StringMap<T> *h, StringHashKey const &key, T const &value);
|
||||
template <typename T> gb_internal void string_map_set (StringMap<T> *h, String const &key, T const &value);
|
||||
template <typename T> gb_internal void string_map_set (StringMap<T> *h, char const *key, T const &value);
|
||||
|
||||
template <typename T> void string_map_remove (StringMap<T> *h, StringHashKey const &key);
|
||||
template <typename T> void string_map_clear (StringMap<T> *h);
|
||||
template <typename T> void string_map_grow (StringMap<T> *h);
|
||||
template <typename T> void string_map_rehash (StringMap<T> *h, isize new_count);
|
||||
template <typename T> void string_map_reserve (StringMap<T> *h, isize cap);
|
||||
template <typename T> gb_internal void string_map_remove (StringMap<T> *h, StringHashKey const &key);
|
||||
template <typename T> gb_internal void string_map_clear (StringMap<T> *h);
|
||||
template <typename T> gb_internal void string_map_grow (StringMap<T> *h);
|
||||
template <typename T> gb_internal void string_map_rehash (StringMap<T> *h, isize new_count);
|
||||
template <typename T> gb_internal void string_map_reserve (StringMap<T> *h, isize cap);
|
||||
|
||||
template <typename T>
|
||||
gb_inline void string_map_init(StringMap<T> *h, gbAllocator a, isize capacity) {
|
||||
gb_internal gb_inline void string_map_init(StringMap<T> *h, gbAllocator a, isize capacity) {
|
||||
capacity = next_pow2_isize(capacity);
|
||||
slice_init(&h->hashes, a, capacity);
|
||||
array_init(&h->entries, a, 0, capacity);
|
||||
@@ -69,7 +69,7 @@ gb_inline void string_map_init(StringMap<T> *h, gbAllocator a, isize capacity) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
gb_inline void string_map_destroy(StringMap<T> *h) {
|
||||
gb_internal gb_inline void string_map_destroy(StringMap<T> *h) {
|
||||
slice_free(&h->hashes, h->entries.allocator);
|
||||
array_free(&h->entries);
|
||||
}
|
||||
@@ -130,7 +130,7 @@ gb_inline void string_map_grow(StringMap<T> *h) {
|
||||
|
||||
|
||||
template <typename T>
|
||||
void string_map_reset_entries(StringMap<T> *h) {
|
||||
gb_internal void string_map_reset_entries(StringMap<T> *h) {
|
||||
for (isize i = 0; i < h->hashes.count; i++) {
|
||||
h->hashes.data[i] = MAP_SENTINEL;
|
||||
}
|
||||
@@ -148,7 +148,7 @@ void string_map_reset_entries(StringMap<T> *h) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void string_map_reserve(StringMap<T> *h, isize cap) {
|
||||
gb_internal void string_map_reserve(StringMap<T> *h, isize cap) {
|
||||
array_reserve(&h->entries, cap);
|
||||
if (h->entries.count*2 < h->hashes.count) {
|
||||
return;
|
||||
@@ -159,12 +159,12 @@ void string_map_reserve(StringMap<T> *h, isize cap) {
|
||||
|
||||
|
||||
template <typename T>
|
||||
void string_map_rehash(StringMap<T> *h, isize new_count) {
|
||||
gb_internal void string_map_rehash(StringMap<T> *h, isize new_count) {
|
||||
string_map_reserve(h, new_count);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T *string_map_get(StringMap<T> *h, StringHashKey const &key) {
|
||||
gb_internal T *string_map_get(StringMap<T> *h, StringHashKey const &key) {
|
||||
isize index = string_map__find(h, key).entry_index;
|
||||
if (index != MAP_SENTINEL) {
|
||||
return &h->entries.data[index].value;
|
||||
@@ -173,34 +173,34 @@ T *string_map_get(StringMap<T> *h, StringHashKey const &key) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
gb_inline T *string_map_get(StringMap<T> *h, String const &key) {
|
||||
gb_internal gb_inline T *string_map_get(StringMap<T> *h, String const &key) {
|
||||
return string_map_get(h, string_hash_string(key));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
gb_inline T *string_map_get(StringMap<T> *h, char const *key) {
|
||||
gb_internal gb_inline T *string_map_get(StringMap<T> *h, char const *key) {
|
||||
return string_map_get(h, string_hash_string(make_string_c(key)));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T &string_map_must_get(StringMap<T> *h, StringHashKey const &key) {
|
||||
gb_internal T &string_map_must_get(StringMap<T> *h, StringHashKey const &key) {
|
||||
isize index = string_map__find(h, key).entry_index;
|
||||
GB_ASSERT(index != MAP_SENTINEL);
|
||||
return h->entries.data[index].value;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
gb_inline T &string_map_must_get(StringMap<T> *h, String const &key) {
|
||||
gb_internal gb_inline T &string_map_must_get(StringMap<T> *h, String const &key) {
|
||||
return string_map_must_get(h, string_hash_string(key));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
gb_inline T &string_map_must_get(StringMap<T> *h, char const *key) {
|
||||
gb_internal gb_inline T &string_map_must_get(StringMap<T> *h, char const *key) {
|
||||
return string_map_must_get(h, string_hash_string(make_string_c(key)));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void string_map_set(StringMap<T> *h, StringHashKey const &key, T const &value) {
|
||||
gb_internal void string_map_set(StringMap<T> *h, StringHashKey const &key, T const &value) {
|
||||
MapIndex index;
|
||||
MapFindResult fr;
|
||||
if (h->hashes.count == 0) {
|
||||
@@ -225,18 +225,18 @@ void string_map_set(StringMap<T> *h, StringHashKey const &key, T const &value) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
gb_inline void string_map_set(StringMap<T> *h, String const &key, T const &value) {
|
||||
gb_internal gb_inline void string_map_set(StringMap<T> *h, String const &key, T const &value) {
|
||||
string_map_set(h, string_hash_string(key), value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
gb_inline void string_map_set(StringMap<T> *h, char const *key, T const &value) {
|
||||
gb_internal gb_inline void string_map_set(StringMap<T> *h, char const *key, T const &value) {
|
||||
string_map_set(h, string_hash_string(make_string_c(key)), value);
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void string_map__erase(StringMap<T> *h, MapFindResult const &fr) {
|
||||
gb_internal void string_map__erase(StringMap<T> *h, MapFindResult const &fr) {
|
||||
MapFindResult last;
|
||||
if (fr.entry_prev == MAP_SENTINEL) {
|
||||
h->hashes.data[fr.hash_index] = h->entries.data[fr.entry_index].next;
|
||||
@@ -257,7 +257,7 @@ void string_map__erase(StringMap<T> *h, MapFindResult const &fr) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void string_map_remove(StringMap<T> *h, StringHashKey const &key) {
|
||||
gb_internal void string_map_remove(StringMap<T> *h, StringHashKey const &key) {
|
||||
MapFindResult fr = string_map__find(h, key);
|
||||
if (fr.entry_index != MAP_SENTINEL) {
|
||||
string_map__erase(h, fr);
|
||||
@@ -265,7 +265,7 @@ void string_map_remove(StringMap<T> *h, StringHashKey const &key) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
gb_inline void string_map_clear(StringMap<T> *h) {
|
||||
gb_internal gb_inline void string_map_clear(StringMap<T> *h) {
|
||||
array_clear(&h->entries);
|
||||
for (isize i = 0; i < h->hashes.count; i++) {
|
||||
h->hashes.data[i] = MAP_SENTINEL;
|
||||
@@ -275,21 +275,21 @@ gb_inline void string_map_clear(StringMap<T> *h) {
|
||||
|
||||
|
||||
template <typename T>
|
||||
StringMapEntry<T> *begin(StringMap<T> &m) {
|
||||
gb_internal StringMapEntry<T> *begin(StringMap<T> &m) {
|
||||
return m.entries.data;
|
||||
}
|
||||
template <typename T>
|
||||
StringMapEntry<T> const *begin(StringMap<T> const &m) {
|
||||
gb_internal StringMapEntry<T> const *begin(StringMap<T> const &m) {
|
||||
return m.entries.data;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
StringMapEntry<T> *end(StringMap<T> &m) {
|
||||
gb_internal StringMapEntry<T> *end(StringMap<T> &m) {
|
||||
return m.entries.data + m.entries.count;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
StringMapEntry<T> const *end(StringMap<T> const &m) {
|
||||
gb_internal StringMapEntry<T> const *end(StringMap<T> const &m) {
|
||||
return m.entries.data + m.entries.count;
|
||||
}
|
||||
@@ -23,9 +23,9 @@ struct ThreadPool {
|
||||
|
||||
};
|
||||
|
||||
THREAD_PROC(thread_pool_thread_proc);
|
||||
gb_internal THREAD_PROC(thread_pool_thread_proc);
|
||||
|
||||
void thread_pool_init(ThreadPool *pool, gbAllocator const &a, isize thread_count, char const *worker_name) {
|
||||
gb_internal void thread_pool_init(ThreadPool *pool, gbAllocator const &a, isize thread_count, char const *worker_name) {
|
||||
pool->allocator = a;
|
||||
pool->stop = false;
|
||||
mutex_init(&pool->mutex);
|
||||
@@ -43,7 +43,7 @@ void thread_pool_init(ThreadPool *pool, gbAllocator const &a, isize thread_count
|
||||
}
|
||||
}
|
||||
|
||||
void thread_pool_destroy(ThreadPool *pool) {
|
||||
gb_internal void thread_pool_destroy(ThreadPool *pool) {
|
||||
mutex_lock(&pool->mutex);
|
||||
pool->stop = true;
|
||||
condition_broadcast(&pool->task_cond);
|
||||
@@ -64,23 +64,23 @@ void thread_pool_destroy(ThreadPool *pool) {
|
||||
condition_destroy(&pool->task_cond);
|
||||
}
|
||||
|
||||
bool thread_pool_queue_empty(ThreadPool *pool) {
|
||||
gb_internal bool thread_pool_queue_empty(ThreadPool *pool) {
|
||||
return pool->task_queue == nullptr;
|
||||
}
|
||||
|
||||
WorkerTask *thread_pool_queue_pop(ThreadPool *pool) {
|
||||
gb_internal WorkerTask *thread_pool_queue_pop(ThreadPool *pool) {
|
||||
GB_ASSERT(pool->task_queue != nullptr);
|
||||
WorkerTask *task = pool->task_queue;
|
||||
pool->task_queue = task->next;
|
||||
return task;
|
||||
}
|
||||
void thread_pool_queue_push(ThreadPool *pool, WorkerTask *task) {
|
||||
gb_internal void thread_pool_queue_push(ThreadPool *pool, WorkerTask *task) {
|
||||
GB_ASSERT(task != nullptr);
|
||||
task->next = pool->task_queue;
|
||||
pool->task_queue = task;
|
||||
}
|
||||
|
||||
bool thread_pool_add_task(ThreadPool *pool, WorkerTaskProc *proc, void *data) {
|
||||
gb_internal bool thread_pool_add_task(ThreadPool *pool, WorkerTaskProc *proc, void *data) {
|
||||
GB_ASSERT(proc != nullptr);
|
||||
mutex_lock(&pool->mutex);
|
||||
WorkerTask *task = gb_alloc_item(permanent_allocator(), WorkerTask);
|
||||
@@ -101,11 +101,11 @@ bool thread_pool_add_task(ThreadPool *pool, WorkerTaskProc *proc, void *data) {
|
||||
}
|
||||
|
||||
|
||||
void thread_pool_do_task(WorkerTask *task) {
|
||||
gb_internal void thread_pool_do_task(WorkerTask *task) {
|
||||
task->do_work(task->data);
|
||||
}
|
||||
|
||||
void thread_pool_wait(ThreadPool *pool) {
|
||||
gb_internal void thread_pool_wait(ThreadPool *pool) {
|
||||
if (pool->threads.count == 0) {
|
||||
while (!thread_pool_queue_empty(pool)) {
|
||||
thread_pool_do_task(thread_pool_queue_pop(pool));
|
||||
@@ -138,7 +138,7 @@ void thread_pool_wait(ThreadPool *pool) {
|
||||
}
|
||||
|
||||
|
||||
THREAD_PROC(thread_pool_thread_proc) {
|
||||
gb_internal THREAD_PROC(thread_pool_thread_proc) {
|
||||
ThreadPool *pool = cast(ThreadPool *)thread->user_data;
|
||||
|
||||
for (;;) {
|
||||
|
||||
@@ -29,43 +29,43 @@ struct Thread {
|
||||
};
|
||||
|
||||
|
||||
void mutex_init (BlockingMutex *m);
|
||||
void mutex_destroy (BlockingMutex *m);
|
||||
void mutex_lock (BlockingMutex *m);
|
||||
bool mutex_try_lock(BlockingMutex *m);
|
||||
void mutex_unlock (BlockingMutex *m);
|
||||
void mutex_init (RecursiveMutex *m);
|
||||
void mutex_destroy (RecursiveMutex *m);
|
||||
void mutex_lock (RecursiveMutex *m);
|
||||
bool mutex_try_lock(RecursiveMutex *m);
|
||||
void mutex_unlock (RecursiveMutex *m);
|
||||
gb_internal void mutex_init (BlockingMutex *m);
|
||||
gb_internal void mutex_destroy (BlockingMutex *m);
|
||||
gb_internal void mutex_lock (BlockingMutex *m);
|
||||
gb_internal bool mutex_try_lock(BlockingMutex *m);
|
||||
gb_internal void mutex_unlock (BlockingMutex *m);
|
||||
gb_internal void mutex_init (RecursiveMutex *m);
|
||||
gb_internal void mutex_destroy (RecursiveMutex *m);
|
||||
gb_internal void mutex_lock (RecursiveMutex *m);
|
||||
gb_internal bool mutex_try_lock(RecursiveMutex *m);
|
||||
gb_internal void mutex_unlock (RecursiveMutex *m);
|
||||
|
||||
void semaphore_init (Semaphore *s);
|
||||
void semaphore_destroy(Semaphore *s);
|
||||
void semaphore_post (Semaphore *s, i32 count);
|
||||
void semaphore_wait (Semaphore *s);
|
||||
void semaphore_release(Semaphore *s) { semaphore_post(s, 1); }
|
||||
gb_internal void semaphore_init (Semaphore *s);
|
||||
gb_internal void semaphore_destroy(Semaphore *s);
|
||||
gb_internal void semaphore_post (Semaphore *s, i32 count);
|
||||
gb_internal void semaphore_wait (Semaphore *s);
|
||||
gb_internal void semaphore_release(Semaphore *s) { semaphore_post(s, 1); }
|
||||
|
||||
|
||||
void condition_init(Condition *c);
|
||||
void condition_destroy(Condition *c);
|
||||
void condition_broadcast(Condition *c);
|
||||
void condition_signal(Condition *c);
|
||||
void condition_wait(Condition *c, BlockingMutex *m);
|
||||
void condition_wait_with_timeout(Condition *c, BlockingMutex *m, u32 timeout_in_ms);
|
||||
gb_internal void condition_init(Condition *c);
|
||||
gb_internal void condition_destroy(Condition *c);
|
||||
gb_internal void condition_broadcast(Condition *c);
|
||||
gb_internal void condition_signal(Condition *c);
|
||||
gb_internal void condition_wait(Condition *c, BlockingMutex *m);
|
||||
gb_internal void condition_wait_with_timeout(Condition *c, BlockingMutex *m, u32 timeout_in_ms);
|
||||
|
||||
u32 thread_current_id(void);
|
||||
gb_internal u32 thread_current_id(void);
|
||||
|
||||
void thread_init (Thread *t);
|
||||
void thread_destroy (Thread *t);
|
||||
void thread_start (Thread *t, ThreadProc *proc, void *data);
|
||||
void thread_start_with_stack(Thread *t, ThreadProc *proc, void *data, isize stack_size);
|
||||
void thread_join (Thread *t);
|
||||
bool thread_is_running (Thread const *t);
|
||||
void thread_set_name (Thread *t, char const *name);
|
||||
gb_internal void thread_init (Thread *t);
|
||||
gb_internal void thread_destroy (Thread *t);
|
||||
gb_internal void thread_start (Thread *t, ThreadProc *proc, void *data);
|
||||
gb_internal void thread_start_with_stack(Thread *t, ThreadProc *proc, void *data, isize stack_size);
|
||||
gb_internal void thread_join (Thread *t);
|
||||
gb_internal bool thread_is_running (Thread const *t);
|
||||
gb_internal void thread_set_name (Thread *t, char const *name);
|
||||
|
||||
void yield_thread(void);
|
||||
void yield_process(void);
|
||||
gb_internal void yield_thread(void);
|
||||
gb_internal void yield_process(void);
|
||||
|
||||
|
||||
struct MutexGuard {
|
||||
@@ -106,36 +106,36 @@ struct MutexGuard {
|
||||
struct BlockingMutex {
|
||||
SRWLOCK srwlock;
|
||||
};
|
||||
void mutex_init(BlockingMutex *m) {
|
||||
gb_internal void mutex_init(BlockingMutex *m) {
|
||||
}
|
||||
void mutex_destroy(BlockingMutex *m) {
|
||||
gb_internal void mutex_destroy(BlockingMutex *m) {
|
||||
}
|
||||
void mutex_lock(BlockingMutex *m) {
|
||||
gb_internal void mutex_lock(BlockingMutex *m) {
|
||||
AcquireSRWLockExclusive(&m->srwlock);
|
||||
}
|
||||
bool mutex_try_lock(BlockingMutex *m) {
|
||||
gb_internal bool mutex_try_lock(BlockingMutex *m) {
|
||||
return !!TryAcquireSRWLockExclusive(&m->srwlock);
|
||||
}
|
||||
void mutex_unlock(BlockingMutex *m) {
|
||||
gb_internal void mutex_unlock(BlockingMutex *m) {
|
||||
ReleaseSRWLockExclusive(&m->srwlock);
|
||||
}
|
||||
|
||||
struct RecursiveMutex {
|
||||
CRITICAL_SECTION win32_critical_section;
|
||||
};
|
||||
void mutex_init(RecursiveMutex *m) {
|
||||
gb_internal void mutex_init(RecursiveMutex *m) {
|
||||
InitializeCriticalSection(&m->win32_critical_section);
|
||||
}
|
||||
void mutex_destroy(RecursiveMutex *m) {
|
||||
gb_internal void mutex_destroy(RecursiveMutex *m) {
|
||||
DeleteCriticalSection(&m->win32_critical_section);
|
||||
}
|
||||
void mutex_lock(RecursiveMutex *m) {
|
||||
gb_internal void mutex_lock(RecursiveMutex *m) {
|
||||
EnterCriticalSection(&m->win32_critical_section);
|
||||
}
|
||||
bool mutex_try_lock(RecursiveMutex *m) {
|
||||
gb_internal bool mutex_try_lock(RecursiveMutex *m) {
|
||||
return TryEnterCriticalSection(&m->win32_critical_section) != 0;
|
||||
}
|
||||
void mutex_unlock(RecursiveMutex *m) {
|
||||
gb_internal void mutex_unlock(RecursiveMutex *m) {
|
||||
LeaveCriticalSection(&m->win32_critical_section);
|
||||
}
|
||||
|
||||
@@ -143,16 +143,16 @@ struct MutexGuard {
|
||||
void *win32_handle;
|
||||
};
|
||||
|
||||
void semaphore_init(Semaphore *s) {
|
||||
gb_internal void semaphore_init(Semaphore *s) {
|
||||
s->win32_handle = CreateSemaphoreA(NULL, 0, I32_MAX, NULL);
|
||||
}
|
||||
void semaphore_destroy(Semaphore *s) {
|
||||
gb_internal void semaphore_destroy(Semaphore *s) {
|
||||
CloseHandle(s->win32_handle);
|
||||
}
|
||||
void semaphore_post(Semaphore *s, i32 count) {
|
||||
gb_internal void semaphore_post(Semaphore *s, i32 count) {
|
||||
ReleaseSemaphore(s->win32_handle, count, NULL);
|
||||
}
|
||||
void semaphore_wait(Semaphore *s) {
|
||||
gb_internal void semaphore_wait(Semaphore *s) {
|
||||
WaitForSingleObjectEx(s->win32_handle, INFINITE, FALSE);
|
||||
}
|
||||
|
||||
@@ -160,20 +160,20 @@ struct MutexGuard {
|
||||
CONDITION_VARIABLE cond;
|
||||
};
|
||||
|
||||
void condition_init(Condition *c) {
|
||||
gb_internal void condition_init(Condition *c) {
|
||||
}
|
||||
void condition_destroy(Condition *c) {
|
||||
gb_internal void condition_destroy(Condition *c) {
|
||||
}
|
||||
void condition_broadcast(Condition *c) {
|
||||
gb_internal void condition_broadcast(Condition *c) {
|
||||
WakeAllConditionVariable(&c->cond);
|
||||
}
|
||||
void condition_signal(Condition *c) {
|
||||
gb_internal void condition_signal(Condition *c) {
|
||||
WakeConditionVariable(&c->cond);
|
||||
}
|
||||
void condition_wait(Condition *c, BlockingMutex *m) {
|
||||
gb_internal void condition_wait(Condition *c, BlockingMutex *m) {
|
||||
SleepConditionVariableSRW(&c->cond, &m->srwlock, INFINITE, 0);
|
||||
}
|
||||
void condition_wait_with_timeout(Condition *c, BlockingMutex *m, u32 timeout_in_ms) {
|
||||
gb_internal void condition_wait_with_timeout(Condition *c, BlockingMutex *m, u32 timeout_in_ms) {
|
||||
SleepConditionVariableSRW(&c->cond, &m->srwlock, timeout_in_ms, 0);
|
||||
}
|
||||
|
||||
@@ -181,19 +181,19 @@ struct MutexGuard {
|
||||
struct BlockingMutex {
|
||||
pthread_mutex_t pthread_mutex;
|
||||
};
|
||||
void mutex_init(BlockingMutex *m) {
|
||||
gb_internal void mutex_init(BlockingMutex *m) {
|
||||
pthread_mutex_init(&m->pthread_mutex, nullptr);
|
||||
}
|
||||
void mutex_destroy(BlockingMutex *m) {
|
||||
gb_internal void mutex_destroy(BlockingMutex *m) {
|
||||
pthread_mutex_destroy(&m->pthread_mutex);
|
||||
}
|
||||
void mutex_lock(BlockingMutex *m) {
|
||||
gb_internal void mutex_lock(BlockingMutex *m) {
|
||||
pthread_mutex_lock(&m->pthread_mutex);
|
||||
}
|
||||
bool mutex_try_lock(BlockingMutex *m) {
|
||||
gb_internal bool mutex_try_lock(BlockingMutex *m) {
|
||||
return pthread_mutex_trylock(&m->pthread_mutex) == 0;
|
||||
}
|
||||
void mutex_unlock(BlockingMutex *m) {
|
||||
gb_internal void mutex_unlock(BlockingMutex *m) {
|
||||
pthread_mutex_unlock(&m->pthread_mutex);
|
||||
}
|
||||
|
||||
@@ -201,21 +201,21 @@ struct MutexGuard {
|
||||
pthread_mutex_t pthread_mutex;
|
||||
pthread_mutexattr_t pthread_mutexattr;
|
||||
};
|
||||
void mutex_init(RecursiveMutex *m) {
|
||||
gb_internal void mutex_init(RecursiveMutex *m) {
|
||||
pthread_mutexattr_init(&m->pthread_mutexattr);
|
||||
pthread_mutexattr_settype(&m->pthread_mutexattr, PTHREAD_MUTEX_RECURSIVE);
|
||||
pthread_mutex_init(&m->pthread_mutex, &m->pthread_mutexattr);
|
||||
}
|
||||
void mutex_destroy(RecursiveMutex *m) {
|
||||
gb_internal void mutex_destroy(RecursiveMutex *m) {
|
||||
pthread_mutex_destroy(&m->pthread_mutex);
|
||||
}
|
||||
void mutex_lock(RecursiveMutex *m) {
|
||||
gb_internal void mutex_lock(RecursiveMutex *m) {
|
||||
pthread_mutex_lock(&m->pthread_mutex);
|
||||
}
|
||||
bool mutex_try_lock(RecursiveMutex *m) {
|
||||
gb_internal bool mutex_try_lock(RecursiveMutex *m) {
|
||||
return pthread_mutex_trylock(&m->pthread_mutex) == 0;
|
||||
}
|
||||
void mutex_unlock(RecursiveMutex *m) {
|
||||
gb_internal void mutex_unlock(RecursiveMutex *m) {
|
||||
pthread_mutex_unlock(&m->pthread_mutex);
|
||||
}
|
||||
|
||||
@@ -224,18 +224,18 @@ struct MutexGuard {
|
||||
semaphore_t osx_handle;
|
||||
};
|
||||
|
||||
void semaphore_init (Semaphore *s) { semaphore_create(mach_task_self(), &s->osx_handle, SYNC_POLICY_FIFO, 0); }
|
||||
void semaphore_destroy(Semaphore *s) { semaphore_destroy(mach_task_self(), s->osx_handle); }
|
||||
void semaphore_post (Semaphore *s, i32 count) { while (count --> 0) semaphore_signal(s->osx_handle); }
|
||||
void semaphore_wait (Semaphore *s) { semaphore_wait(s->osx_handle); }
|
||||
gb_internal void semaphore_init (Semaphore *s) { semaphore_create(mach_task_self(), &s->osx_handle, SYNC_POLICY_FIFO, 0); }
|
||||
gb_internal void semaphore_destroy(Semaphore *s) { semaphore_destroy(mach_task_self(), s->osx_handle); }
|
||||
gb_internal void semaphore_post (Semaphore *s, i32 count) { while (count --> 0) semaphore_signal(s->osx_handle); }
|
||||
gb_internal void semaphore_wait (Semaphore *s) { semaphore_wait(s->osx_handle); }
|
||||
#elif defined(GB_SYSTEM_UNIX)
|
||||
struct Semaphore {
|
||||
sem_t unix_handle;
|
||||
};
|
||||
|
||||
void semaphore_init (Semaphore *s) { sem_init(&s->unix_handle, 0, 0); }
|
||||
void semaphore_destroy(Semaphore *s) { sem_destroy(&s->unix_handle); }
|
||||
void semaphore_post (Semaphore *s, i32 count) { while (count --> 0) sem_post(&s->unix_handle); }
|
||||
gb_internal void semaphore_init (Semaphore *s) { sem_init(&s->unix_handle, 0, 0); }
|
||||
gb_internal void semaphore_destroy(Semaphore *s) { sem_destroy(&s->unix_handle); }
|
||||
gb_internal void semaphore_post (Semaphore *s, i32 count) { while (count --> 0) sem_post(&s->unix_handle); }
|
||||
void semaphore_wait (Semaphore *s) { int i; do { i = sem_wait(&s->unix_handle); } while (i == -1 && errno == EINTR); }
|
||||
#else
|
||||
#error Implement Semaphore for this platform
|
||||
@@ -246,22 +246,22 @@ struct MutexGuard {
|
||||
pthread_cond_t pthread_cond;
|
||||
};
|
||||
|
||||
void condition_init(Condition *c) {
|
||||
gb_internal void condition_init(Condition *c) {
|
||||
pthread_cond_init(&c->pthread_cond, NULL);
|
||||
}
|
||||
void condition_destroy(Condition *c) {
|
||||
gb_internal void condition_destroy(Condition *c) {
|
||||
pthread_cond_destroy(&c->pthread_cond);
|
||||
}
|
||||
void condition_broadcast(Condition *c) {
|
||||
gb_internal void condition_broadcast(Condition *c) {
|
||||
pthread_cond_broadcast(&c->pthread_cond);
|
||||
}
|
||||
void condition_signal(Condition *c) {
|
||||
gb_internal void condition_signal(Condition *c) {
|
||||
pthread_cond_signal(&c->pthread_cond);
|
||||
}
|
||||
void condition_wait(Condition *c, BlockingMutex *m) {
|
||||
gb_internal void condition_wait(Condition *c, BlockingMutex *m) {
|
||||
pthread_cond_wait(&c->pthread_cond, &m->pthread_mutex);
|
||||
}
|
||||
void condition_wait_with_timeout(Condition *c, BlockingMutex *m, u32 timeout_in_ms) {
|
||||
gb_internal void condition_wait_with_timeout(Condition *c, BlockingMutex *m, u32 timeout_in_ms) {
|
||||
struct timespec abstime = {};
|
||||
abstime.tv_sec = timeout_in_ms/1000;
|
||||
abstime.tv_nsec = cast(long)(timeout_in_ms%1000)*1e6;
|
||||
@@ -279,7 +279,7 @@ struct Barrier {
|
||||
isize thread_count;
|
||||
};
|
||||
|
||||
void barrier_init(Barrier *b, isize thread_count) {
|
||||
gb_internal void barrier_init(Barrier *b, isize thread_count) {
|
||||
mutex_init(&b->mutex);
|
||||
condition_init(&b->cond);
|
||||
b->index = 0;
|
||||
@@ -287,13 +287,13 @@ void barrier_init(Barrier *b, isize thread_count) {
|
||||
b->thread_count = 0;
|
||||
}
|
||||
|
||||
void barrier_destroy(Barrier *b) {
|
||||
gb_internal void barrier_destroy(Barrier *b) {
|
||||
condition_destroy(&b->cond);
|
||||
mutex_destroy(&b->mutex);
|
||||
}
|
||||
|
||||
// Returns true if it is the leader
|
||||
bool barrier_wait(Barrier *b) {
|
||||
gb_internal bool barrier_wait(Barrier *b) {
|
||||
mutex_lock(&b->mutex);
|
||||
defer (mutex_unlock(&b->mutex));
|
||||
isize local_gen = b->generation_id;
|
||||
@@ -313,7 +313,7 @@ bool barrier_wait(Barrier *b) {
|
||||
|
||||
|
||||
|
||||
u32 thread_current_id(void) {
|
||||
gb_internal u32 thread_current_id(void) {
|
||||
u32 thread_id;
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
#if defined(GB_ARCH_32_BIT) && defined(GB_CPU_X86)
|
||||
@@ -340,7 +340,7 @@ u32 thread_current_id(void) {
|
||||
}
|
||||
|
||||
|
||||
gb_inline void yield_thread(void) {
|
||||
gb_internal gb_inline void yield_thread(void) {
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
_mm_pause();
|
||||
#elif defined(GB_SYSTEM_OSX)
|
||||
@@ -358,7 +358,7 @@ gb_inline void yield_thread(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
gb_inline void yield(void) {
|
||||
gb_internal gb_inline void yield(void) {
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
YieldProcessor();
|
||||
#else
|
||||
@@ -367,7 +367,7 @@ gb_inline void yield(void) {
|
||||
}
|
||||
|
||||
|
||||
void thread_init(Thread *t) {
|
||||
gb_internal void thread_init(Thread *t) {
|
||||
gb_zero_item(t);
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
t->win32_handle = INVALID_HANDLE_VALUE;
|
||||
@@ -378,27 +378,27 @@ void thread_init(Thread *t) {
|
||||
semaphore_init(t->semaphore);
|
||||
}
|
||||
|
||||
void thread_destroy(Thread *t) {
|
||||
gb_internal void thread_destroy(Thread *t) {
|
||||
thread_join(t);
|
||||
semaphore_destroy(t->semaphore);
|
||||
gb_free(heap_allocator(), t->semaphore);
|
||||
}
|
||||
|
||||
|
||||
void gb__thread_run(Thread *t) {
|
||||
gb_internal void gb__thread_run(Thread *t) {
|
||||
semaphore_release(t->semaphore);
|
||||
t->return_value = t->proc(t);
|
||||
}
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
DWORD __stdcall internal_thread_proc(void *arg) {
|
||||
gb_internal DWORD __stdcall internal_thread_proc(void *arg) {
|
||||
Thread *t = cast(Thread *)arg;
|
||||
t->is_running.store(true);
|
||||
gb__thread_run(t);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
void *internal_thread_proc(void *arg) {
|
||||
gb_internal void *internal_thread_proc(void *arg) {
|
||||
#if (GB_SYSTEM_LINUX)
|
||||
// NOTE: Don't permit any signal delivery to threads on Linux.
|
||||
sigset_t mask = {};
|
||||
@@ -413,9 +413,9 @@ void gb__thread_run(Thread *t) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void thread_start(Thread *t, ThreadProc *proc, void *user_data) { thread_start_with_stack(t, proc, user_data, 0); }
|
||||
gb_internal void thread_start(Thread *t, ThreadProc *proc, void *user_data) { thread_start_with_stack(t, proc, user_data, 0); }
|
||||
|
||||
void thread_start_with_stack(Thread *t, ThreadProc *proc, void *user_data, isize stack_size) {
|
||||
gb_internal void thread_start_with_stack(Thread *t, ThreadProc *proc, void *user_data, isize stack_size) {
|
||||
GB_ASSERT(!t->is_running.load());
|
||||
GB_ASSERT(proc != NULL);
|
||||
t->proc = proc;
|
||||
@@ -441,7 +441,7 @@ void thread_start_with_stack(Thread *t, ThreadProc *proc, void *user_data, isize
|
||||
semaphore_wait(t->semaphore);
|
||||
}
|
||||
|
||||
void thread_join(Thread *t) {
|
||||
gb_internal void thread_join(Thread *t) {
|
||||
if (!t->is_running.load()) {
|
||||
return;
|
||||
}
|
||||
@@ -457,9 +457,9 @@ void thread_join(Thread *t) {
|
||||
t->is_running.store(false);
|
||||
}
|
||||
|
||||
bool thread_is_running(Thread const *t) { return t->is_running.load(); }
|
||||
gb_internal bool thread_is_running(Thread const *t) { return t->is_running.load(); }
|
||||
|
||||
void thread_set_name(Thread *t, char const *name) {
|
||||
gb_internal void thread_set_name(Thread *t, char const *name) {
|
||||
#if defined(GB_COMPILER_MSVC)
|
||||
#pragma pack(push, 8)
|
||||
typedef struct {
|
||||
|
||||
@@ -13,13 +13,13 @@ struct Timings {
|
||||
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
u64 win32_time_stamp_time_now(void) {
|
||||
gb_internal u64 win32_time_stamp_time_now(void) {
|
||||
LARGE_INTEGER counter;
|
||||
QueryPerformanceCounter(&counter);
|
||||
return counter.QuadPart;
|
||||
}
|
||||
|
||||
u64 win32_time_stamp__freq(void) {
|
||||
gb_internal u64 win32_time_stamp__freq(void) {
|
||||
gb_local_persist LARGE_INTEGER win32_perf_count_freq = {0};
|
||||
if (!win32_perf_count_freq.QuadPart) {
|
||||
QueryPerformanceFrequency(&win32_perf_count_freq);
|
||||
@@ -33,11 +33,11 @@ u64 win32_time_stamp__freq(void) {
|
||||
|
||||
#include <mach/mach_time.h>
|
||||
|
||||
u64 osx_time_stamp_time_now(void) {
|
||||
gb_internal u64 osx_time_stamp_time_now(void) {
|
||||
return mach_absolute_time();
|
||||
}
|
||||
|
||||
u64 osx_time_stamp__freq(void) {
|
||||
gb_internal u64 osx_time_stamp__freq(void) {
|
||||
mach_timebase_info_data_t data;
|
||||
data.numer = 0;
|
||||
data.denom = 0;
|
||||
@@ -55,14 +55,14 @@ u64 osx_time_stamp__freq(void) {
|
||||
|
||||
#include <time.h>
|
||||
|
||||
u64 unix_time_stamp_time_now(void) {
|
||||
gb_internal u64 unix_time_stamp_time_now(void) {
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
|
||||
return (ts.tv_sec * 1000000000) + ts.tv_nsec;
|
||||
}
|
||||
|
||||
u64 unix_time_stamp__freq(void) {
|
||||
gb_internal u64 unix_time_stamp__freq(void) {
|
||||
gb_local_persist u64 freq = 0;
|
||||
|
||||
if (freq == 0) {
|
||||
@@ -80,7 +80,7 @@ u64 unix_time_stamp__freq(void) {
|
||||
#error Implement system
|
||||
#endif
|
||||
|
||||
u64 time_stamp_time_now(void) {
|
||||
gb_internal u64 time_stamp_time_now(void) {
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
return win32_time_stamp_time_now();
|
||||
#elif defined(GB_SYSTEM_OSX)
|
||||
@@ -92,7 +92,7 @@ u64 time_stamp_time_now(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
u64 time_stamp__freq(void) {
|
||||
gb_internal u64 time_stamp__freq(void) {
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
return win32_time_stamp__freq();
|
||||
#elif defined(GB_SYSTEM_OSX)
|
||||
@@ -104,44 +104,44 @@ u64 time_stamp__freq(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
TimeStamp make_time_stamp(String const &label) {
|
||||
gb_internal TimeStamp make_time_stamp(String const &label) {
|
||||
TimeStamp ts = {0};
|
||||
ts.start = time_stamp_time_now();
|
||||
ts.label = label;
|
||||
return ts;
|
||||
}
|
||||
|
||||
void timings_init(Timings *t, String const &label, isize buffer_size) {
|
||||
gb_internal void timings_init(Timings *t, String const &label, isize buffer_size) {
|
||||
array_init(&t->sections, heap_allocator(), 0, buffer_size);
|
||||
t->total = make_time_stamp(label);
|
||||
t->freq = time_stamp__freq();
|
||||
}
|
||||
|
||||
void timings_destroy(Timings *t) {
|
||||
gb_internal void timings_destroy(Timings *t) {
|
||||
array_free(&t->sections);
|
||||
}
|
||||
|
||||
void timings__stop_current_section(Timings *t) {
|
||||
gb_internal void timings__stop_current_section(Timings *t) {
|
||||
if (t->sections.count > 0) {
|
||||
t->sections[t->sections.count-1].finish = time_stamp_time_now();
|
||||
}
|
||||
}
|
||||
|
||||
void timings_start_section(Timings *t, String const &label) {
|
||||
gb_internal void timings_start_section(Timings *t, String const &label) {
|
||||
timings__stop_current_section(t);
|
||||
array_add(&t->sections, make_time_stamp(label));
|
||||
}
|
||||
|
||||
f64 time_stamp_as_s(TimeStamp const &ts, u64 freq) {
|
||||
gb_internal f64 time_stamp_as_s(TimeStamp const &ts, u64 freq) {
|
||||
GB_ASSERT_MSG(ts.finish >= ts.start, "time_stamp_as_ms - %.*s", LIT(ts.label));
|
||||
return cast(f64)(ts.finish - ts.start) / cast(f64)freq;
|
||||
}
|
||||
|
||||
f64 time_stamp_as_ms(TimeStamp const &ts, u64 freq) {
|
||||
gb_internal f64 time_stamp_as_ms(TimeStamp const &ts, u64 freq) {
|
||||
return 1000.0*time_stamp_as_s(ts, freq);
|
||||
}
|
||||
|
||||
f64 time_stamp_as_us(TimeStamp const &ts, u64 freq) {
|
||||
gb_internal f64 time_stamp_as_us(TimeStamp const &ts, u64 freq) {
|
||||
return 1000000.0*time_stamp_as_s(ts, freq);
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ enum TimingUnit {
|
||||
|
||||
char const *timing_unit_strings[TimingUnit_COUNT] = {"s", "ms", "us"};
|
||||
|
||||
f64 time_stamp(TimeStamp const &ts, u64 freq, TimingUnit unit) {
|
||||
gb_internal f64 time_stamp(TimeStamp const &ts, u64 freq, TimingUnit unit) {
|
||||
switch (unit) {
|
||||
case TimingUnit_Millisecond: return time_stamp_as_ms(ts, freq);
|
||||
case TimingUnit_Microsecond: return time_stamp_as_us(ts, freq);
|
||||
@@ -169,7 +169,7 @@ f64 time_stamp(TimeStamp const &ts, u64 freq, TimingUnit unit) {
|
||||
}
|
||||
}
|
||||
|
||||
void timings_print_all(Timings *t, TimingUnit unit = TimingUnit_Millisecond, bool timings_are_finalized = false) {
|
||||
gb_internal void timings_print_all(Timings *t, TimingUnit unit = TimingUnit_Millisecond, bool timings_are_finalized = false) {
|
||||
isize const SPACES_LEN = 256;
|
||||
char SPACES[SPACES_LEN+1] = {0};
|
||||
gb_memset(SPACES, ' ', SPACES_LEN);
|
||||
|
||||
@@ -151,10 +151,10 @@ gb_global isize max_keyword_size = 11;
|
||||
gb_global bool keyword_indices[16] = {};
|
||||
|
||||
|
||||
gb_inline u32 keyword_hash(u8 const *text, isize len) {
|
||||
gb_internal gb_inline u32 keyword_hash(u8 const *text, isize len) {
|
||||
return fnv32a(text, len);
|
||||
}
|
||||
void add_keyword_hash_entry(String const &s, TokenKind kind) {
|
||||
gb_internal void add_keyword_hash_entry(String const &s, TokenKind kind) {
|
||||
max_keyword_size = gb_max(max_keyword_size, s.len);
|
||||
|
||||
keyword_indices[s.len] = true;
|
||||
@@ -169,7 +169,7 @@ void add_keyword_hash_entry(String const &s, TokenKind kind) {
|
||||
entry->kind = kind;
|
||||
entry->text = s;
|
||||
}
|
||||
void init_keyword_hash_table(void) {
|
||||
gb_internal void init_keyword_hash_table(void) {
|
||||
for (i32 kind = Token__KeywordBegin+1; kind < Token__KeywordEnd; kind++) {
|
||||
add_keyword_hash_entry(token_strings[kind], cast(TokenKind)kind);
|
||||
}
|
||||
@@ -191,8 +191,8 @@ void init_keyword_hash_table(void) {
|
||||
gb_global Array<String> global_file_path_strings; // index is file id
|
||||
gb_global Array<struct AstFile *> global_files; // index is file id
|
||||
|
||||
String get_file_path_string(i32 index);
|
||||
struct AstFile *thread_safe_get_ast_file_from_id(i32 index);
|
||||
gb_internal String get_file_path_string(i32 index);
|
||||
gb_internal struct AstFile *thread_safe_get_ast_file_from_id(i32 index);
|
||||
|
||||
struct TokenPos {
|
||||
i32 file_id;
|
||||
@@ -201,7 +201,7 @@ struct TokenPos {
|
||||
i32 column; // starting at 1
|
||||
};
|
||||
|
||||
i32 token_pos_cmp(TokenPos const &a, TokenPos const &b) {
|
||||
gb_internal i32 token_pos_cmp(TokenPos const &a, TokenPos const &b) {
|
||||
if (a.offset != b.offset) {
|
||||
return (a.offset < b.offset) ? -1 : +1;
|
||||
}
|
||||
@@ -214,12 +214,12 @@ i32 token_pos_cmp(TokenPos const &a, TokenPos const &b) {
|
||||
return string_compare(get_file_path_string(a.file_id), get_file_path_string(b.file_id));
|
||||
}
|
||||
|
||||
bool operator==(TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) == 0; }
|
||||
bool operator!=(TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) != 0; }
|
||||
bool operator< (TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) < 0; }
|
||||
bool operator<=(TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) <= 0; }
|
||||
bool operator> (TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) > 0; }
|
||||
bool operator>=(TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) >= 0; }
|
||||
gb_internal gb_inline bool operator==(TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) == 0; }
|
||||
gb_internal gb_inline bool operator!=(TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) != 0; }
|
||||
gb_internal gb_inline bool operator< (TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) < 0; }
|
||||
gb_internal gb_inline bool operator<=(TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) <= 0; }
|
||||
gb_internal gb_inline bool operator> (TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) > 0; }
|
||||
gb_internal gb_inline bool operator>=(TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) >= 0; }
|
||||
|
||||
|
||||
TokenPos token_pos_add_column(TokenPos pos) {
|
||||
@@ -243,36 +243,36 @@ struct Token {
|
||||
Token empty_token = {Token_Invalid};
|
||||
Token blank_token = {Token_Ident, 0, {cast(u8 *)"_", 1}};
|
||||
|
||||
Token make_token_ident(String s) {
|
||||
gb_internal Token make_token_ident(String s) {
|
||||
Token t = {Token_Ident, 0, s};
|
||||
return t;
|
||||
}
|
||||
Token make_token_ident(char const *s) {
|
||||
gb_internal Token make_token_ident(char const *s) {
|
||||
Token t = {Token_Ident, 0, make_string_c(s)};
|
||||
return t;
|
||||
}
|
||||
|
||||
bool token_is_newline(Token const &tok) {
|
||||
gb_internal bool token_is_newline(Token const &tok) {
|
||||
return tok.kind == Token_Semicolon && tok.string == "\n";
|
||||
}
|
||||
|
||||
gb_inline bool token_is_literal(TokenKind t) {
|
||||
gb_internal gb_inline bool token_is_literal(TokenKind t) {
|
||||
return gb_is_between(t, Token__LiteralBegin+1, Token__LiteralEnd-1);
|
||||
}
|
||||
gb_inline bool token_is_operator(TokenKind t) {
|
||||
gb_internal gb_inline bool token_is_operator(TokenKind t) {
|
||||
return gb_is_between(t, Token__OperatorBegin+1, Token__OperatorEnd-1);
|
||||
}
|
||||
gb_inline bool token_is_keyword(TokenKind t) {
|
||||
gb_internal gb_inline bool token_is_keyword(TokenKind t) {
|
||||
return gb_is_between(t, Token__KeywordBegin+1, Token__KeywordEnd-1);
|
||||
}
|
||||
gb_inline bool token_is_comparison(TokenKind t) {
|
||||
gb_internal gb_inline bool token_is_comparison(TokenKind t) {
|
||||
return gb_is_between(t, Token__ComparisonBegin+1, Token__ComparisonEnd-1);
|
||||
}
|
||||
gb_inline bool token_is_shift(TokenKind t) {
|
||||
gb_internal gb_inline bool token_is_shift(TokenKind t) {
|
||||
return t == Token_Shl || t == Token_Shr;
|
||||
}
|
||||
|
||||
gb_inline void print_token(Token t) { gb_printf("%.*s\n", LIT(t.string)); }
|
||||
gb_internal gb_inline void print_token(Token t) { gb_printf("%.*s\n", LIT(t.string)); }
|
||||
|
||||
#include "error.cpp"
|
||||
|
||||
@@ -309,7 +309,7 @@ struct Tokenizer {
|
||||
};
|
||||
|
||||
|
||||
void tokenizer_err(Tokenizer *t, char const *msg, ...) {
|
||||
gb_internal void tokenizer_err(Tokenizer *t, char const *msg, ...) {
|
||||
va_list va;
|
||||
i32 column = t->column_minus_one+1;
|
||||
if (column < 1) {
|
||||
@@ -328,7 +328,7 @@ void tokenizer_err(Tokenizer *t, char const *msg, ...) {
|
||||
t->error_count++;
|
||||
}
|
||||
|
||||
void tokenizer_err(Tokenizer *t, TokenPos const &pos, char const *msg, ...) {
|
||||
gb_internal void tokenizer_err(Tokenizer *t, TokenPos const &pos, char const *msg, ...) {
|
||||
va_list va;
|
||||
i32 column = t->column_minus_one+1;
|
||||
if (column < 1) {
|
||||
@@ -342,7 +342,7 @@ void tokenizer_err(Tokenizer *t, TokenPos const &pos, char const *msg, ...) {
|
||||
t->error_count++;
|
||||
}
|
||||
|
||||
void advance_to_next_rune(Tokenizer *t) {
|
||||
gb_internal void advance_to_next_rune(Tokenizer *t) {
|
||||
if (t->curr_rune == '\n') {
|
||||
t->column_minus_one = -1;
|
||||
t->line_count++;
|
||||
@@ -372,7 +372,7 @@ void advance_to_next_rune(Tokenizer *t) {
|
||||
}
|
||||
}
|
||||
|
||||
void init_tokenizer_with_data(Tokenizer *t, String const &fullpath, void const *data, isize size) {
|
||||
gb_internal void init_tokenizer_with_data(Tokenizer *t, String const &fullpath, void const *data, isize size) {
|
||||
t->fullpath = fullpath;
|
||||
t->line_count = 1;
|
||||
|
||||
@@ -386,7 +386,7 @@ void init_tokenizer_with_data(Tokenizer *t, String const &fullpath, void const *
|
||||
}
|
||||
}
|
||||
|
||||
TokenizerInitError loaded_file_error_map_to_tokenizer[LoadedFile_COUNT] = {
|
||||
gb_global TokenizerInitError loaded_file_error_map_to_tokenizer[LoadedFile_COUNT] = {
|
||||
TokenizerInit_None, /*LoadedFile_None*/
|
||||
TokenizerInit_Empty, /*LoadedFile_Empty*/
|
||||
TokenizerInit_FileTooLarge, /*LoadedFile_FileTooLarge*/
|
||||
@@ -395,7 +395,7 @@ TokenizerInitError loaded_file_error_map_to_tokenizer[LoadedFile_COUNT] = {
|
||||
TokenizerInit_Permission, /*LoadedFile_Permission*/
|
||||
};
|
||||
|
||||
TokenizerInitError init_tokenizer_from_fullpath(Tokenizer *t, String const &fullpath, bool copy_file_contents) {
|
||||
gb_internal TokenizerInitError init_tokenizer_from_fullpath(Tokenizer *t, String const &fullpath, bool copy_file_contents) {
|
||||
LoadedFileError file_err = load_file_32(
|
||||
alloc_cstring(temporary_allocator(), fullpath),
|
||||
&t->loaded_file,
|
||||
@@ -416,7 +416,7 @@ TokenizerInitError init_tokenizer_from_fullpath(Tokenizer *t, String const &full
|
||||
return err;
|
||||
}
|
||||
|
||||
gb_inline i32 digit_value(Rune r) {
|
||||
gb_internal gb_inline i32 digit_value(Rune r) {
|
||||
switch (r) {
|
||||
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
|
||||
return r - '0';
|
||||
@@ -428,20 +428,20 @@ gb_inline i32 digit_value(Rune r) {
|
||||
return 16; // NOTE(bill): Larger than highest possible
|
||||
}
|
||||
|
||||
gb_inline void scan_mantissa(Tokenizer *t, i32 base) {
|
||||
gb_internal gb_inline void scan_mantissa(Tokenizer *t, i32 base) {
|
||||
while (digit_value(t->curr_rune) < base || t->curr_rune == '_') {
|
||||
advance_to_next_rune(t);
|
||||
}
|
||||
}
|
||||
|
||||
u8 peek_byte(Tokenizer *t, isize offset=0) {
|
||||
gb_internal u8 peek_byte(Tokenizer *t, isize offset=0) {
|
||||
if (t->read_curr+offset < t->end) {
|
||||
return t->read_curr[offset];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void scan_number_to_token(Tokenizer *t, Token *token, bool seen_decimal_point) {
|
||||
gb_internal void scan_number_to_token(Tokenizer *t, Token *token, bool seen_decimal_point) {
|
||||
token->kind = Token_Integer;
|
||||
token->string = {t->curr, 1};
|
||||
token->pos.file_id = t->curr_file_id;
|
||||
@@ -566,7 +566,7 @@ end:
|
||||
}
|
||||
|
||||
|
||||
bool scan_escape(Tokenizer *t) {
|
||||
gb_internal bool scan_escape(Tokenizer *t) {
|
||||
isize len = 0;
|
||||
u32 base = 0, max = 0, x = 0;
|
||||
|
||||
@@ -633,13 +633,13 @@ bool scan_escape(Tokenizer *t) {
|
||||
}
|
||||
|
||||
|
||||
gb_inline void tokenizer_skip_line(Tokenizer *t) {
|
||||
gb_internal gb_inline void tokenizer_skip_line(Tokenizer *t) {
|
||||
while (t->curr_rune != '\n' && t->curr_rune != GB_RUNE_EOF) {
|
||||
advance_to_next_rune(t);
|
||||
}
|
||||
}
|
||||
|
||||
gb_inline void tokenizer_skip_whitespace(Tokenizer *t, bool on_newline) {
|
||||
gb_internal gb_inline void tokenizer_skip_whitespace(Tokenizer *t, bool on_newline) {
|
||||
if (on_newline) {
|
||||
for (;;) {
|
||||
switch (t->curr_rune) {
|
||||
@@ -666,7 +666,7 @@ gb_inline void tokenizer_skip_whitespace(Tokenizer *t, bool on_newline) {
|
||||
}
|
||||
}
|
||||
|
||||
void tokenizer_get_token(Tokenizer *t, Token *token, int repeat=0) {
|
||||
gb_internal void tokenizer_get_token(Tokenizer *t, Token *token, int repeat=0) {
|
||||
tokenizer_skip_whitespace(t, t->insert_semicolon);
|
||||
|
||||
token->kind = Token_Invalid;
|
||||
|
||||
241
src/types.cpp
241
src/types.cpp
@@ -2571,20 +2571,6 @@ bool lookup_subtype_polymorphic_selection(Type *dst, Type *src, Selection *sel)
|
||||
|
||||
|
||||
|
||||
|
||||
Type *strip_type_aliasing(Type *x) {
|
||||
if (x == nullptr) {
|
||||
return x;
|
||||
}
|
||||
if (x->kind == Type_Named) {
|
||||
Entity *e = x->Named.type_name;
|
||||
if (e != nullptr && e->kind == Entity_TypeName && e->TypeName.is_type_alias) {
|
||||
return x->Named.base;
|
||||
}
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
bool are_types_identical_internal(Type *x, Type *y, bool check_tuple_names);
|
||||
|
||||
bool are_types_identical(Type *x, Type *y) {
|
||||
@@ -2605,193 +2591,156 @@ bool are_types_identical_internal(Type *x, Type *y, bool check_tuple_names) {
|
||||
return false;
|
||||
}
|
||||
|
||||
x = strip_type_aliasing(x);
|
||||
y = strip_type_aliasing(y);
|
||||
if (x->kind == Type_Named) {
|
||||
Entity *e = x->Named.type_name;
|
||||
if (e != nullptr && e->kind == Entity_TypeName && e->TypeName.is_type_alias) {
|
||||
x = x->Named.base;
|
||||
}
|
||||
}
|
||||
if (y->kind == Type_Named) {
|
||||
Entity *e = y->Named.type_name;
|
||||
if (e != nullptr && e->kind == Entity_TypeName && e->TypeName.is_type_alias) {
|
||||
y = y->Named.base;
|
||||
}
|
||||
}
|
||||
if (x->kind != y->kind) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (x->kind) {
|
||||
case Type_Generic:
|
||||
if (y->kind == Type_Generic) {
|
||||
return are_types_identical(x->Generic.specialized, y->Generic.specialized);
|
||||
}
|
||||
break;
|
||||
return are_types_identical(x->Generic.specialized, y->Generic.specialized);
|
||||
|
||||
case Type_Basic:
|
||||
if (y->kind == Type_Basic) {
|
||||
return x->Basic.kind == y->Basic.kind;
|
||||
}
|
||||
break;
|
||||
return x->Basic.kind == y->Basic.kind;
|
||||
|
||||
case Type_EnumeratedArray:
|
||||
if (y->kind == Type_EnumeratedArray) {
|
||||
return are_types_identical(x->EnumeratedArray.index, y->EnumeratedArray.index) &&
|
||||
are_types_identical(x->EnumeratedArray.elem, y->EnumeratedArray.elem);
|
||||
}
|
||||
break;
|
||||
return are_types_identical(x->EnumeratedArray.index, y->EnumeratedArray.index) &&
|
||||
are_types_identical(x->EnumeratedArray.elem, y->EnumeratedArray.elem);
|
||||
|
||||
case Type_Array:
|
||||
if (y->kind == Type_Array) {
|
||||
return (x->Array.count == y->Array.count) && are_types_identical(x->Array.elem, y->Array.elem);
|
||||
}
|
||||
break;
|
||||
return (x->Array.count == y->Array.count) && are_types_identical(x->Array.elem, y->Array.elem);
|
||||
|
||||
case Type_Matrix:
|
||||
if (y->kind == Type_Matrix) {
|
||||
return x->Matrix.row_count == y->Matrix.row_count &&
|
||||
x->Matrix.column_count == y->Matrix.column_count &&
|
||||
are_types_identical(x->Matrix.elem, y->Matrix.elem);
|
||||
}
|
||||
break;
|
||||
return x->Matrix.row_count == y->Matrix.row_count &&
|
||||
x->Matrix.column_count == y->Matrix.column_count &&
|
||||
are_types_identical(x->Matrix.elem, y->Matrix.elem);
|
||||
|
||||
case Type_DynamicArray:
|
||||
if (y->kind == Type_DynamicArray) {
|
||||
return are_types_identical(x->DynamicArray.elem, y->DynamicArray.elem);
|
||||
}
|
||||
break;
|
||||
return are_types_identical(x->DynamicArray.elem, y->DynamicArray.elem);
|
||||
|
||||
case Type_Slice:
|
||||
if (y->kind == Type_Slice) {
|
||||
return are_types_identical(x->Slice.elem, y->Slice.elem);
|
||||
}
|
||||
break;
|
||||
return are_types_identical(x->Slice.elem, y->Slice.elem);
|
||||
|
||||
case Type_BitSet:
|
||||
if (y->kind == Type_BitSet) {
|
||||
return are_types_identical(x->BitSet.elem, y->BitSet.elem) &&
|
||||
are_types_identical(x->BitSet.underlying, y->BitSet.underlying) &&
|
||||
x->BitSet.lower == y->BitSet.lower &&
|
||||
x->BitSet.upper == y->BitSet.upper;
|
||||
}
|
||||
break;
|
||||
return are_types_identical(x->BitSet.elem, y->BitSet.elem) &&
|
||||
are_types_identical(x->BitSet.underlying, y->BitSet.underlying) &&
|
||||
x->BitSet.lower == y->BitSet.lower &&
|
||||
x->BitSet.upper == y->BitSet.upper;
|
||||
|
||||
|
||||
case Type_Enum:
|
||||
return x == y; // NOTE(bill): All enums are unique
|
||||
|
||||
case Type_Union:
|
||||
if (y->kind == Type_Union) {
|
||||
if (x->Union.variants.count == y->Union.variants.count &&
|
||||
x->Union.custom_align == y->Union.custom_align &&
|
||||
x->Union.kind == y->Union.kind) {
|
||||
// NOTE(bill): zeroth variant is nullptr
|
||||
for_array(i, x->Union.variants) {
|
||||
if (!are_types_identical(x->Union.variants[i], y->Union.variants[i])) {
|
||||
return false;
|
||||
}
|
||||
if (x->Union.variants.count == y->Union.variants.count &&
|
||||
x->Union.custom_align == y->Union.custom_align &&
|
||||
x->Union.kind == y->Union.kind) {
|
||||
// NOTE(bill): zeroth variant is nullptr
|
||||
for_array(i, x->Union.variants) {
|
||||
if (!are_types_identical(x->Union.variants[i], y->Union.variants[i])) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case Type_Struct:
|
||||
if (y->kind == Type_Struct) {
|
||||
if (x->Struct.is_raw_union == y->Struct.is_raw_union &&
|
||||
x->Struct.fields.count == y->Struct.fields.count &&
|
||||
x->Struct.is_packed == y->Struct.is_packed &&
|
||||
x->Struct.custom_align == y->Struct.custom_align &&
|
||||
x->Struct.soa_kind == y->Struct.soa_kind &&
|
||||
x->Struct.soa_count == y->Struct.soa_count &&
|
||||
are_types_identical(x->Struct.soa_elem, y->Struct.soa_elem)) {
|
||||
// TODO(bill); Fix the custom alignment rule
|
||||
for_array(i, x->Struct.fields) {
|
||||
Entity *xf = x->Struct.fields[i];
|
||||
Entity *yf = y->Struct.fields[i];
|
||||
if (xf->kind != yf->kind) {
|
||||
return false;
|
||||
}
|
||||
if (!are_types_identical(xf->type, yf->type)) {
|
||||
return false;
|
||||
}
|
||||
if (xf->token.string != yf->token.string) {
|
||||
return false;
|
||||
}
|
||||
if (x->Struct.tags[i] != y->Struct.tags[i]) {
|
||||
return false;
|
||||
}
|
||||
u64 xf_flags = (xf->flags&EntityFlags_IsSubtype);
|
||||
u64 yf_flags = (yf->flags&EntityFlags_IsSubtype);
|
||||
if (xf_flags != yf_flags) {
|
||||
return false;
|
||||
}
|
||||
if (x->Struct.is_raw_union == y->Struct.is_raw_union &&
|
||||
x->Struct.fields.count == y->Struct.fields.count &&
|
||||
x->Struct.is_packed == y->Struct.is_packed &&
|
||||
x->Struct.custom_align == y->Struct.custom_align &&
|
||||
x->Struct.soa_kind == y->Struct.soa_kind &&
|
||||
x->Struct.soa_count == y->Struct.soa_count &&
|
||||
are_types_identical(x->Struct.soa_elem, y->Struct.soa_elem)) {
|
||||
// TODO(bill); Fix the custom alignment rule
|
||||
for_array(i, x->Struct.fields) {
|
||||
Entity *xf = x->Struct.fields[i];
|
||||
Entity *yf = y->Struct.fields[i];
|
||||
if (xf->kind != yf->kind) {
|
||||
return false;
|
||||
}
|
||||
if (!are_types_identical(xf->type, yf->type)) {
|
||||
return false;
|
||||
}
|
||||
if (xf->token.string != yf->token.string) {
|
||||
return false;
|
||||
}
|
||||
if (x->Struct.tags[i] != y->Struct.tags[i]) {
|
||||
return false;
|
||||
}
|
||||
u64 xf_flags = (xf->flags&EntityFlags_IsSubtype);
|
||||
u64 yf_flags = (yf->flags&EntityFlags_IsSubtype);
|
||||
if (xf_flags != yf_flags) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case Type_Pointer:
|
||||
if (y->kind == Type_Pointer) {
|
||||
return are_types_identical(x->Pointer.elem, y->Pointer.elem);
|
||||
}
|
||||
break;
|
||||
return are_types_identical(x->Pointer.elem, y->Pointer.elem);
|
||||
|
||||
case Type_MultiPointer:
|
||||
if (y->kind == Type_MultiPointer) {
|
||||
return are_types_identical(x->MultiPointer.elem, y->MultiPointer.elem);
|
||||
}
|
||||
break;
|
||||
return are_types_identical(x->MultiPointer.elem, y->MultiPointer.elem);
|
||||
|
||||
case Type_SoaPointer:
|
||||
if (y->kind == Type_SoaPointer) {
|
||||
return are_types_identical(x->SoaPointer.elem, y->SoaPointer.elem);
|
||||
}
|
||||
break;
|
||||
return are_types_identical(x->SoaPointer.elem, y->SoaPointer.elem);
|
||||
|
||||
case Type_Named:
|
||||
if (y->kind == Type_Named) {
|
||||
return x->Named.type_name == y->Named.type_name;
|
||||
}
|
||||
break;
|
||||
return x->Named.type_name == y->Named.type_name;
|
||||
|
||||
case Type_Tuple:
|
||||
if (y->kind == Type_Tuple) {
|
||||
if (x->Tuple.variables.count == y->Tuple.variables.count &&
|
||||
x->Tuple.is_packed == y->Tuple.is_packed) {
|
||||
for_array(i, x->Tuple.variables) {
|
||||
Entity *xe = x->Tuple.variables[i];
|
||||
Entity *ye = y->Tuple.variables[i];
|
||||
if (xe->kind != ye->kind || !are_types_identical(xe->type, ye->type)) {
|
||||
return false;
|
||||
}
|
||||
if (check_tuple_names) {
|
||||
if (xe->token.string != ye->token.string) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (xe->kind == Entity_Constant && !compare_exact_values(Token_CmpEq, xe->Constant.value, ye->Constant.value)) {
|
||||
// NOTE(bill): This is needed for polymorphic procedures
|
||||
if (x->Tuple.variables.count == y->Tuple.variables.count &&
|
||||
x->Tuple.is_packed == y->Tuple.is_packed) {
|
||||
for_array(i, x->Tuple.variables) {
|
||||
Entity *xe = x->Tuple.variables[i];
|
||||
Entity *ye = y->Tuple.variables[i];
|
||||
if (xe->kind != ye->kind || !are_types_identical(xe->type, ye->type)) {
|
||||
return false;
|
||||
}
|
||||
if (check_tuple_names) {
|
||||
if (xe->token.string != ye->token.string) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
if (xe->kind == Entity_Constant && !compare_exact_values(Token_CmpEq, xe->Constant.value, ye->Constant.value)) {
|
||||
// NOTE(bill): This is needed for polymorphic procedures
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case Type_Proc:
|
||||
if (y->kind == Type_Proc) {
|
||||
return x->Proc.calling_convention == y->Proc.calling_convention &&
|
||||
x->Proc.c_vararg == y->Proc.c_vararg &&
|
||||
x->Proc.variadic == y->Proc.variadic &&
|
||||
x->Proc.diverging == y->Proc.diverging &&
|
||||
x->Proc.optional_ok == y->Proc.optional_ok &&
|
||||
are_types_identical(x->Proc.params, y->Proc.params) &&
|
||||
are_types_identical(x->Proc.results, y->Proc.results);
|
||||
}
|
||||
break;
|
||||
return x->Proc.calling_convention == y->Proc.calling_convention &&
|
||||
x->Proc.c_vararg == y->Proc.c_vararg &&
|
||||
x->Proc.variadic == y->Proc.variadic &&
|
||||
x->Proc.diverging == y->Proc.diverging &&
|
||||
x->Proc.optional_ok == y->Proc.optional_ok &&
|
||||
are_types_identical(x->Proc.params, y->Proc.params) &&
|
||||
are_types_identical(x->Proc.results, y->Proc.results);
|
||||
|
||||
case Type_Map:
|
||||
if (y->kind == Type_Map) {
|
||||
return are_types_identical(x->Map.key, y->Map.key) &&
|
||||
are_types_identical(x->Map.value, y->Map.value);
|
||||
}
|
||||
break;
|
||||
return are_types_identical(x->Map.key, y->Map.key) &&
|
||||
are_types_identical(x->Map.value, y->Map.value);
|
||||
|
||||
case Type_SimdVector:
|
||||
if (y->kind == Type_SimdVector) {
|
||||
if (x->SimdVector.count == y->SimdVector.count) {
|
||||
return are_types_identical(x->SimdVector.elem, y->SimdVector.elem);
|
||||
}
|
||||
if (x->SimdVector.count == y->SimdVector.count) {
|
||||
return are_types_identical(x->SimdVector.elem, y->SimdVector.elem);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ extern "C" {
|
||||
#pragma warning(pop)
|
||||
|
||||
|
||||
bool rune_is_letter(Rune r) {
|
||||
gb_internal bool rune_is_letter(Rune r) {
|
||||
if (r < 0x80) {
|
||||
if (r == '_') {
|
||||
return true;
|
||||
@@ -25,14 +25,14 @@ bool rune_is_letter(Rune r) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool rune_is_digit(Rune r) {
|
||||
gb_internal bool rune_is_digit(Rune r) {
|
||||
if (r < 0x80) {
|
||||
return (cast(u32)r - '0') < 10;
|
||||
}
|
||||
return utf8proc_category(r) == UTF8PROC_CATEGORY_ND;
|
||||
}
|
||||
|
||||
bool rune_is_letter_or_digit(Rune r) {
|
||||
gb_internal bool rune_is_letter_or_digit(Rune r) {
|
||||
if (r < 0x80) {
|
||||
if (r == '_') {
|
||||
return true;
|
||||
@@ -55,7 +55,7 @@ bool rune_is_letter_or_digit(Rune r) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool rune_is_whitespace(Rune r) {
|
||||
gb_internal bool rune_is_whitespace(Rune r) {
|
||||
switch (r) {
|
||||
case ' ':
|
||||
case '\t':
|
||||
@@ -99,7 +99,7 @@ gb_global Utf8AcceptRange const global__utf8_accept_ranges[] = {
|
||||
};
|
||||
|
||||
|
||||
isize utf8_decode(u8 const *str, isize str_len, Rune *codepoint_out) {
|
||||
gb_internal isize utf8_decode(u8 const *str, isize str_len, Rune *codepoint_out) {
|
||||
isize width = 0;
|
||||
Rune codepoint = GB_RUNE_INVALID;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user