mirror of
https://github.com/Ed94/WATL_Exercise.git
synced 2025-08-04 22:32:43 -07:00
finished translating string operations to odin (next is file system)
This commit is contained in:
@@ -1680,7 +1680,7 @@ Str8 str8__fmt(Str8 fmt_template, Slice_A2_Str8* entries) {
|
||||
inline
|
||||
void str8cache__init(Str8Cache* cache, Opts_str8cache_init* opts) {
|
||||
assert(cache != nullptr);
|
||||
assert(opts != nullptr);
|
||||
assert(opts != nullptr);
|
||||
assert(opts->str_reserve.proc != nullptr);
|
||||
assert(opts->cell_reserve.proc != nullptr);
|
||||
assert(opts->tbl_backing.proc != nullptr);
|
||||
@@ -1783,7 +1783,9 @@ void str8gen_append_str8(Str8Gen* gen, Str8 str){
|
||||
slice_assert(result);
|
||||
Slice_Byte to_copy = { result.ptr + gen->len, result.len - gen->len };
|
||||
slice_copy(to_copy, slice_byte(str));
|
||||
gen->ptr = cast(UTF8*, result.ptr); gen->len = result.len;
|
||||
gen->ptr = cast(UTF8*, result.ptr);
|
||||
gen->len += str.len;
|
||||
gen->cap = max(gen->len , gen->cap); // TODO(Ed): Arenas currently hide total capacity before growth. Problably better todo classic append to actually track this.
|
||||
}
|
||||
void str8gen__append_fmt(Str8Gen* gen, Str8 fmt_template, Slice_A2_Str8* entries){
|
||||
local_persist Byte tbl_mem[kilo(32)]; FArena tbl_arena = farena_make(slice_fmem(tbl_mem));
|
||||
@@ -1792,8 +1794,8 @@ void str8gen__append_fmt(Str8Gen* gen, Str8 fmt_template, Slice_A2_Str8* entries
|
||||
if (buffer.len < kilo(16)) {
|
||||
Slice_Byte result = mem_grow(gen->backing, str8gen_slice_byte(* gen), kilo(16) + gen->cap );
|
||||
slice_assert(result);
|
||||
gen->ptr = result.ptr;
|
||||
gen->cap = result.len;
|
||||
gen->ptr = result.ptr;
|
||||
gen->cap += kilo(16);
|
||||
buffer = (Slice_Byte){ cast(Byte*, gen->ptr + gen->len), gen->cap - gen->len };
|
||||
}
|
||||
Str8 result = str8__fmt_kt1l(gen->backing, & buffer, kt, fmt_template);
|
||||
|
@@ -13,6 +13,7 @@ main :: proc()
|
||||
|
||||
import "base:builtin"
|
||||
import "base:intrinsics"
|
||||
import "base:runtime"
|
||||
|
||||
//region Package Mappings
|
||||
abs :: builtin.abs
|
||||
@@ -20,6 +21,11 @@ min :: builtin.min
|
||||
max :: builtin.max
|
||||
clamp :: builtin.clamp
|
||||
|
||||
ainfo :: proc {
|
||||
farena_ainfo,
|
||||
varena_ainfo,
|
||||
arena_ainfo,
|
||||
}
|
||||
alloc :: proc {
|
||||
mem_alloc,
|
||||
alloc_type,
|
||||
@@ -109,11 +115,11 @@ memory_copy_non_overlapping :: proc "contextless" (dst, src: rawptr, len: int) -
|
||||
return dst
|
||||
}
|
||||
|
||||
SliceBytes :: struct {
|
||||
SliceByte :: struct {
|
||||
data: [^]byte,
|
||||
len: int
|
||||
}
|
||||
SliceRaw :: struct ($Type: typeid) {
|
||||
SliceRaw :: struct ($Type: typeid) {
|
||||
data: [^]Type,
|
||||
len: int,
|
||||
}
|
||||
@@ -125,8 +131,8 @@ slice_assert :: #force_inline proc (s: $SliceType / []$Type) {
|
||||
}
|
||||
slice_end :: #force_inline proc "contextless" (s : $SliceType / []$Type) -> ^Type { return & s[len(s) - 1] }
|
||||
|
||||
@(require_results) slice_to_bytes :: proc "contextless" (s: []$Type) -> []byte { return ([^]byte)(raw_data(s))[:len(s) * size_of(Type)] }
|
||||
@(require_results) slice_raw :: proc "contextless" (s: []$Type) -> SliceRaw(Type) { return transmute(SliceRaw(Type)) s }
|
||||
@(require_results) slice_to_bytes :: proc "contextless" (s: []$Type) -> []byte { return ([^]byte)(raw_data(s))[:len(s) * size_of(Type)] }
|
||||
@(require_results) slice_raw :: proc "contextless" (s: []$Type) -> SliceRaw(Type) { return transmute(SliceRaw(Type)) s }
|
||||
|
||||
slice_zero :: proc "contextless" (data: $SliceType / []$Type) { zero(raw_data(data), size_of(Type) * len(data)) }
|
||||
slice_copy :: proc "contextless" (dst, src: $SliceType / []$Type) -> int {
|
||||
@@ -319,7 +325,7 @@ alloc_type :: proc(ainfo: AllocatorInfo, $Type: typeid, alignment: int = MEMORY
|
||||
ainfo.procedure(input, & output)
|
||||
return transmute(^Type) raw_data(output.allocation)
|
||||
}
|
||||
alloc_slice :: proc(ainfo: AllocatorInfo, $SliceType: []$Type, num : int) -> []Type {
|
||||
alloc_slice :: proc(ainfo: AllocatorInfo, $SliceType: typeid / []$Type, num : int, alignment: int = MEMORY_ALIGNMENT_DEFAULT, no_zero: b32 = false) -> []Type {
|
||||
assert(ainfo.procedure != nil)
|
||||
input := AllocatorProc_In {
|
||||
data = ainfo.data,
|
||||
@@ -329,7 +335,7 @@ alloc_slice :: proc(ainfo: AllocatorInfo, $SliceType: []$Type, num : int) -> []T
|
||||
}
|
||||
output: AllocatorProc_Out
|
||||
ainfo.procedure(input, & output)
|
||||
return transmute([]Type) Raw_Slice { raw_data(output.allocation), num }
|
||||
return transmute([]Type) slice(raw_data(output.allocation), num)
|
||||
}
|
||||
//endregion Allocator Interface
|
||||
|
||||
@@ -459,6 +465,7 @@ farena_allocator_proc :: proc(input: AllocatorProc_In, output: ^AllocatorProc_Ou
|
||||
output.save_point = farena_save(arena^)
|
||||
}
|
||||
}
|
||||
farena_ainfo :: #force_inline proc "contextless" (arena : ^FArena) -> AllocatorInfo { return AllocatorInfo{farena_allocator_proc, arena} }
|
||||
//endregion FArena
|
||||
|
||||
//region OS
|
||||
@@ -709,6 +716,7 @@ varena_allocator_proc :: proc(input: AllocatorProc_In, output: ^AllocatorProc_Ou
|
||||
output.save_point = varena_save(vm)
|
||||
}
|
||||
}
|
||||
varena_ainfo :: #force_inline proc "contextless" (arena : ^VArena) -> AllocatorInfo { return AllocatorInfo{varena_allocator_proc, arena} }
|
||||
//endregion VArena
|
||||
|
||||
//region Arena (Chained Arena)
|
||||
@@ -850,7 +858,7 @@ arena_allocator_proc :: proc(input: AllocatorProc_In, output: ^AllocatorProc_Out
|
||||
if input.op == .Grow {
|
||||
zero(cursor(new_alloc)[len(input.old_allocation):], input.requested_size - len(input.old_allocation))
|
||||
}
|
||||
output.allocation = slice_to_bytes(new_alloc)
|
||||
output.allocation = new_alloc
|
||||
output.continuity_break = true
|
||||
|
||||
case .Shrink:
|
||||
@@ -888,6 +896,7 @@ arena_allocator_proc :: proc(input: AllocatorProc_In, output: ^AllocatorProc_Out
|
||||
output.save_point = arena_save(arena)
|
||||
}
|
||||
}
|
||||
arena_ainfo :: #force_inline proc "contextless" (arena : ^Arena) -> AllocatorInfo { return AllocatorInfo{arena_allocator_proc, arena} }
|
||||
//endregion Arena (Casey-Ryan Composite Arena)
|
||||
|
||||
//region Hashing
|
||||
@@ -907,7 +916,7 @@ KT1L_Meta :: struct {
|
||||
slot_size: uintptr,
|
||||
kt_value_offset: uintptr,
|
||||
type_width: uintptr,
|
||||
type_name: string,
|
||||
type: typeid,
|
||||
}
|
||||
kt1l_populate_slice_a2_Slice_Byte :: proc(kt: ^[]byte, backing: AllocatorInfo, values: []byte, num_values: int, m: KT1L_Meta) {
|
||||
assert(kt != nil)
|
||||
@@ -915,14 +924,14 @@ kt1l_populate_slice_a2_Slice_Byte :: proc(kt: ^[]byte, backing: AllocatorInfo, v
|
||||
table_size_bytes := num_values * int(m.slot_size)
|
||||
kt^ = mem_alloc(backing, table_size_bytes)
|
||||
slice_assert(kt ^)
|
||||
kt_raw : SliceBytes = transmute(SliceBytes) kt^
|
||||
for cursor in 0 ..< cast(uintptr) num_values {
|
||||
slot_offset := cursor * m.slot_size // slot id
|
||||
kt_raw : SliceByte = transmute(SliceByte) kt^
|
||||
for id in 0 ..< cast(uintptr) num_values {
|
||||
slot_offset := id * m.slot_size // slot id
|
||||
slot_cursor := kt_raw.data[slot_offset:] // slots[id] type: KT1L_<Type>
|
||||
slot_key := cast(^u64) slot_cursor // slots[id].key type: U64
|
||||
slot_value := slice(slot_cursor[m.kt_value_offset:], m.type_width) // slots[id].value type: <Type>
|
||||
a2_offset := cursor * m.type_width * 2 // a2 entry id
|
||||
a2_cursor := slice_cursor(values)[a2_offset:] // a2_entries[id] type: A2_<Type>
|
||||
a2_offset := id * m.type_width * 2 // a2 entry id
|
||||
a2_cursor := cursor(values)[a2_offset:] // a2_entries[id] type: A2_<Type>
|
||||
a2_key := (transmute(^[]byte) a2_cursor) ^ // a2_entries[id].key type: <Type>
|
||||
a2_value := slice(a2_cursor[m.type_width:], m.type_width) // a2_entries[id].value type: <Type>
|
||||
copy(slot_value, a2_value) // slots[id].value = a2_entries[id].value
|
||||
@@ -932,12 +941,12 @@ kt1l_populate_slice_a2_Slice_Byte :: proc(kt: ^[]byte, backing: AllocatorInfo, v
|
||||
}
|
||||
kt1l_populate_slice_a2 :: proc($Type: typeid, kt: ^[]KT1L_Slot(Type), backing: AllocatorInfo, values: [][2]Type) {
|
||||
assert(kt != nil)
|
||||
values_bytes := transmute([]byte) SliceBytes{data = raw_data(values), len = len(values) * size_of([2]Type)}
|
||||
values_bytes := slice(transmute([^]u8) raw_data(values), len(values) * size_of([2]Type))
|
||||
kt1l_populate_slice_a2_Slice_Byte(transmute(^[]byte) kt, backing, values_bytes, len(values), {
|
||||
slot_size = size_of(KT1L_Slot(Type)),
|
||||
kt_value_offset = offset_of(KT1L_Slot(Type), KT1L_Slot(Type).value),
|
||||
kt_value_offset = offset_of(KT1L_Slot(Type), value),
|
||||
type_width = size_of(Type),
|
||||
type_name = #type_string(Type),
|
||||
type = Type,
|
||||
})
|
||||
}
|
||||
//endregion Key Table 1-Layer Linear (KT1L)
|
||||
@@ -974,7 +983,7 @@ KT1CX_ByteMeta :: struct {
|
||||
cell_depth: int,
|
||||
cell_size: int,
|
||||
type_width: int,
|
||||
type_name: string,
|
||||
type: typeid,
|
||||
}
|
||||
KT1CX_InfoMeta :: struct {
|
||||
cell_pool_size: int,
|
||||
@@ -985,7 +994,7 @@ KT1CX_InfoMeta :: struct {
|
||||
cell_depth: int,
|
||||
cell_size: int,
|
||||
type_width: int,
|
||||
type_name: string,
|
||||
type: typeid,
|
||||
}
|
||||
KT1CX_Info :: struct {
|
||||
backing_table: AllocatorInfo,
|
||||
@@ -999,7 +1008,7 @@ kt1cx_init :: proc(info: KT1CX_Info, m: KT1CX_InfoMeta, result: ^KT1CX_Byte) {
|
||||
assert(m.cell_pool_size >= 4 * Kilo)
|
||||
assert(m.table_size >= 4 * Kilo)
|
||||
assert(m.type_width > 0)
|
||||
table_raw := transmute(SliceBytes) mem_alloc(info.backing_table, m.table_size * m.cell_size)
|
||||
table_raw := transmute(SliceByte) mem_alloc(info.backing_table, m.table_size * m.cell_size)
|
||||
slice_assert(transmute([]byte) table_raw)
|
||||
result.cell_pool = mem_alloc(info.backing_cells, m.cell_pool_size * m.cell_size)
|
||||
slice_assert(result.cell_pool)
|
||||
@@ -1011,7 +1020,7 @@ kt1cx_clear :: proc(kt: KT1CX_Byte, m: KT1CX_ByteMeta) {
|
||||
table_len := len(kt.table) * m.cell_size
|
||||
for ; cell_cursor != end(kt.table); cell_cursor = cell_cursor[m.cell_size:] // for cell, cell_id in kt.table.cells
|
||||
{
|
||||
slots := SliceBytes { cell_cursor, m.cell_depth * m.slot_size } // slots = cell.slots
|
||||
slots := SliceByte { cell_cursor, m.cell_depth * m.slot_size } // slots = cell.slots
|
||||
slot_cursor := slots.data
|
||||
for;; {
|
||||
slot := slice(slot_cursor, m.slot_size) // slot = slots[slot_id]
|
||||
@@ -1065,9 +1074,9 @@ kt1cx_get :: proc(kt: KT1CX_Byte, key: u64, m: KT1CX_ByteMeta) -> ^byte {
|
||||
kt1cx_set :: proc(kt: KT1CX_Byte, key: u64, value: []byte, backing_cells: AllocatorInfo, m: KT1CX_ByteMeta) -> ^byte {
|
||||
hash_index := kt1cx_slot_id(kt, key, m)
|
||||
cell_offset := uintptr(hash_index) * uintptr(m.cell_size)
|
||||
cell := SliceBytes{& kt.table[cell_offset], m.cell_size}
|
||||
cell_cursor := cursor(kt.table)[cell_offset:] // KT1CX_Cell(Type) cell = kt.table[hash_index]
|
||||
{
|
||||
slots := SliceBytes {cell.data, m.cell_depth * m.slot_size}
|
||||
slots := SliceByte {cell_cursor, m.cell_depth * m.slot_size} // cell.slots
|
||||
slot_cursor := slots.data
|
||||
for ;;
|
||||
{
|
||||
@@ -1081,11 +1090,11 @@ kt1cx_set :: proc(kt: KT1CX_Byte, key: u64, value: []byte, backing_cells: Alloca
|
||||
return cast(^byte) slot_cursor
|
||||
}
|
||||
if slot_cursor == end(transmute([]byte) slots) {
|
||||
curr_cell := transmute(^KT1CX_Byte_Cell) (uintptr(cell.data) + m.cell_next_offset)
|
||||
curr_cell := transmute(^KT1CX_Byte_Cell) (uintptr(cell_cursor) + m.cell_next_offset) // curr_cell = cell
|
||||
if curr_cell != nil {
|
||||
slots.data = curr_cell.next
|
||||
slot_cursor = curr_cell.next
|
||||
cell.data = curr_cell.next
|
||||
cell_cursor = curr_cell.next
|
||||
continue
|
||||
}
|
||||
else {
|
||||
@@ -1271,10 +1280,18 @@ str8_fmt_kt1l :: proc(ainfo: AllocatorInfo, _buffer: ^[]byte, table: []KT1L_Slot
|
||||
}
|
||||
|
||||
str8_fmt_backed :: proc(tbl_ainfo, buf_ainfo: AllocatorInfo, fmt_template: string, entries: [][2]string) -> string {
|
||||
return {}
|
||||
kt: []KT1L_Slot(string); kt1l_populate_slice_a2(string, & kt, tbl_ainfo, entries)
|
||||
buf_size := Kilo * 64
|
||||
buffer := mem_alloc(buf_ainfo, buf_size)
|
||||
result := str8_fmt_kt1l(buf_ainfo, & buffer, kt, fmt_template)
|
||||
return result
|
||||
}
|
||||
str8_fmt_tmp :: proc(fmt_template: string, entries: [][2]string) -> string {
|
||||
return {}
|
||||
@static tbl_mem: [Kilo * 32]byte; tbl_arena := farena_make(tbl_mem[:])
|
||||
@static buf_mem: [Kilo * 64]byte; buffer := buf_mem[:]
|
||||
kt: []KT1L_Slot(string); kt1l_populate_slice_a2(string, & kt, ainfo(& tbl_arena), entries)
|
||||
result := str8_fmt_kt1l({}, & buffer, kt, fmt_template)
|
||||
return result
|
||||
}
|
||||
|
||||
Str8Cache_CELL_DEPTH :: 4
|
||||
@@ -1288,39 +1305,129 @@ Str8Cache :: struct {
|
||||
tbl_backing: AllocatorInfo,
|
||||
kt: KT1CX_Str8,
|
||||
}
|
||||
str8cache_init :: proc(cache: ^Str8Cache, str_reserve, cell_reserve, tbl_backing: AllocatorInfo, cell_pool_size, table_size: int) {
|
||||
str8cache_init :: proc(cache: ^Str8Cache, str_reserve, cell_reserve, tbl_backing: AllocatorInfo, cell_pool_size := Kilo, table_size := Kilo) {
|
||||
assert(cache != nil)
|
||||
assert(str_reserve.procedure != nil)
|
||||
assert(cell_reserve.procedure != nil)
|
||||
assert(tbl_backing.procedure != nil)
|
||||
cache.str_reserve = str_reserve
|
||||
cache.cell_reserve = cell_reserve
|
||||
cache.tbl_backing = tbl_backing
|
||||
info := KT1CX_Info {
|
||||
backing_cells = cell_reserve,
|
||||
backing_table = tbl_backing,
|
||||
}
|
||||
m := KT1CX_InfoMeta {
|
||||
cell_pool_size = cell_pool_size,
|
||||
table_size = table_size,
|
||||
slot_size = size_of(KT1CX_Slot_Str8),
|
||||
slot_key_offset = offset_of(KT1CX_Slot_Str8, key),
|
||||
cell_next_offset = offset_of(KT1CX_Cell_Str8, next),
|
||||
cell_depth = Str8Cache_CELL_DEPTH,
|
||||
type_width = size_of(string),
|
||||
type = string
|
||||
}
|
||||
kt1cx_init(info, m, transmute(^KT1CX_Byte) & cache.kt)
|
||||
return
|
||||
}
|
||||
str8cache_make :: proc(str_reserve, cell_reserve, tbl_backing: AllocatorInfo, cell_pool_size, table_size: int) -> Str8Cache {
|
||||
cache : Str8Cache; str8cache_init(& cache, str_reserve, cell_reserve, tbl_backing, cell_pool_size, table_size); return cache
|
||||
}
|
||||
str8cache_clear :: proc(kt: KT1CX_Str8) {
|
||||
kt1cx_assert(kt)
|
||||
kt1cx_clear(kt1cx_byte(kt), {
|
||||
slot_size = size_of(KT1CX_Slot_Str8),
|
||||
slot_key_offset = offset_of(KT1CX_Slot_Str8, key),
|
||||
cell_next_offset = offset_of(KT1CX_Cell_Str8, next),
|
||||
cell_depth = Str8Cache_CELL_DEPTH,
|
||||
cell_size = size_of(KT1CX_Cell_Str8),
|
||||
type_width = size_of(string),
|
||||
type = string,
|
||||
})
|
||||
}
|
||||
str8cache_get :: proc(kt: KT1CX_Str8, key: u64) -> ^string {
|
||||
return nil
|
||||
kt1cx_assert(kt)
|
||||
result := kt1cx_get(kt1cx_byte(kt), key, {
|
||||
slot_size = size_of(KT1CX_Slot_Str8),
|
||||
slot_key_offset = offset_of(KT1CX_Slot_Str8, key),
|
||||
cell_next_offset = offset_of(KT1CX_Cell_Str8, next),
|
||||
cell_depth = Str8Cache_CELL_DEPTH,
|
||||
cell_size = size_of(KT1CX_Cell_Str8),
|
||||
type_width = size_of(string),
|
||||
type = string,
|
||||
})
|
||||
return transmute(^string) result
|
||||
}
|
||||
str8cache_set :: proc(kt: KT1CX_Str8, key: u64, value: string, str_reserve, cell_reserve: AllocatorInfo) -> ^string {
|
||||
return nil
|
||||
kt1cx_assert(kt)
|
||||
slice_assert(transmute([]byte) value)
|
||||
assert(str_reserve.procedure != nil)
|
||||
assert(cell_reserve.procedure != nil)
|
||||
entry := kt1cx_set(kt1cx_byte(kt), key, transmute([]byte) value, cell_reserve, {
|
||||
slot_size = size_of(KT1CX_Slot_Str8),
|
||||
slot_key_offset = offset_of(KT1CX_Slot_Str8, key),
|
||||
cell_next_offset = offset_of(KT1CX_Cell_Str8, next),
|
||||
cell_depth = Str8Cache_CELL_DEPTH,
|
||||
cell_size = size_of(KT1CX_Cell_Str8),
|
||||
type_width = size_of(string),
|
||||
type = string,
|
||||
})
|
||||
assert(entry != nil)
|
||||
result := transmute(^string) entry
|
||||
is_empty := len(result) == 0
|
||||
if is_empty {
|
||||
result ^ = transmute(string) alloc_slice(str_reserve, []u8, len(value))
|
||||
copy(result ^, value)
|
||||
}
|
||||
return result
|
||||
}
|
||||
cache_str8 :: proc(cache: ^Str8Cache, str: string) -> ^string {
|
||||
return nil
|
||||
cache_str8 :: proc(cache: ^Str8Cache, str: string) -> string {
|
||||
assert(cache != nil)
|
||||
key: u64 = 0; hash64_djb8(& key, transmute([]byte) str)
|
||||
result := str8cache_set(cache.kt, key, str, cache.str_reserve, cache.cell_reserve)
|
||||
return result ^
|
||||
}
|
||||
|
||||
Str8Gen :: struct {
|
||||
backing: AllocatorInfo,
|
||||
ptr: ^u8,
|
||||
len: int,
|
||||
cap: int,
|
||||
ptr: [^]u8,
|
||||
len: int,
|
||||
cap: int,
|
||||
}
|
||||
str8gen_init :: proc(gen: ^Str8Gen, ainfo: AllocatorInfo) {
|
||||
|
||||
assert(gen != nil)
|
||||
gen.backing = ainfo
|
||||
gen.ptr = raw_data(mem_alloc(ainfo, Kilo * 4))
|
||||
assert(gen.ptr != nil)
|
||||
gen.len = 0
|
||||
gen.cap = Kilo * 4
|
||||
}
|
||||
str8gen_make :: proc(ainfo: AllocatorInfo) -> Str8Gen { gen: Str8Gen; str8gen_init(& gen, ainfo); return gen }
|
||||
str8gen_to_bytes :: proc(gen: Str8Gen) -> []byte { return transmute([]byte) SliceBytes {data = gen.ptr, len = gen.len} }
|
||||
str8_from_str8gen :: proc(gen: Str8Gen) -> string { return transmute(string) SliceBytes {data = gen.ptr, len = gen.len} }
|
||||
str8gen_to_bytes :: proc(gen: Str8Gen) -> []byte { return transmute([]byte) SliceByte {data = gen.ptr, len = gen.len} }
|
||||
str8_from_str8gen :: proc(gen: Str8Gen) -> string { return transmute(string) SliceByte {data = gen.ptr, len = gen.len} }
|
||||
|
||||
str8gen_append_str8 :: proc(gen: ^Str8Gen, str: string) {
|
||||
result := mem_grow(gen.backing, str8gen_to_bytes(gen ^), len(str) + gen.len)
|
||||
slice_assert(result)
|
||||
to_copy := slice(cursor(result)[gen.len:], len(result) - gen.len)
|
||||
copy(to_copy, transmute([]byte) str)
|
||||
gen.ptr = transmute(^u8) raw_data(result)
|
||||
gen.len = len(result)
|
||||
gen.cap = max(gen.len, gen.cap) // TODO(Ed): Arenas currently hide total capacity before growth. Problably better todo classic append to actually track this.
|
||||
}
|
||||
str8gen_append_fmt :: proc(gen: ^Str8Gen, fmt_template: string, tokens: [][2]string) {
|
||||
@static tbl_mem: [Kilo * 32]byte; tbl_arena := farena_make(tbl_mem[:])
|
||||
kt: []KT1L_Slot(string); kt1l_populate_slice_a2(string, & kt, ainfo(& tbl_arena), tokens)
|
||||
buffer := slice(gen.ptr[gen.len:], gen.cap - gen.len)
|
||||
if len(buffer) < Kilo * 16 {
|
||||
result := mem_grow(gen.backing, str8gen_to_bytes(gen ^), Kilo * 16 + gen.cap)
|
||||
slice_assert(result)
|
||||
gen.ptr = raw_data(result)
|
||||
gen.cap += Kilo * 16
|
||||
buffer = slice(gen.ptr[gen.len:], gen.cap - gen.len)
|
||||
}
|
||||
result := str8_fmt_kt1l(gen.backing, & buffer, kt, fmt_template)
|
||||
gen.len += len(result)
|
||||
}
|
||||
//#endregion String Operations
|
||||
|
||||
|
@@ -1,14 +0,0 @@
|
||||
// raddbg 0.9.18 project file
|
||||
|
||||
recent_file: path: "c/watl.v0.msvc.c"
|
||||
target:
|
||||
{
|
||||
executable: "build/watl.v0.msvc.exe"
|
||||
working_directory: C
|
||||
enabled: 1
|
||||
}
|
||||
breakpoint:
|
||||
{
|
||||
source_location: "c/watl.v0.msvc.c:2227:1"
|
||||
hit_count: 0
|
||||
}
|
@@ -1,154 +0,0 @@
|
||||
// raddbg 0.9.18 user file
|
||||
|
||||
recent_project: path: "watl_exercise.proj"
|
||||
window:
|
||||
{
|
||||
size: 2048.000000 1152.000000
|
||||
pos: 234 234
|
||||
monitor: "\\\\.\\DISPLAY1"
|
||||
maximized
|
||||
panels:
|
||||
{
|
||||
0.683614: selected getting_started text:
|
||||
{
|
||||
selected
|
||||
expression: "file:\"C:/projects/WATL_Exercise/c/watl.v0.msvc.c\".data"
|
||||
auto: 1
|
||||
query: input: ""
|
||||
cursor_line: 2227
|
||||
cursor_column: 1
|
||||
mark_line: 2227
|
||||
mark_column: 1
|
||||
}
|
||||
0.316386:
|
||||
{
|
||||
watch: expression: "query:targets"
|
||||
watch:
|
||||
{
|
||||
selected
|
||||
expression: ""
|
||||
watch: "listing.ptr.text()"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
keybindings:
|
||||
{
|
||||
{ kill_all f5 shift }
|
||||
{ step_into_inst f11 alt }
|
||||
{ step_over_inst f10 alt }
|
||||
{ step_out f11 shift }
|
||||
{ halt x ctrl shift }
|
||||
{ halt pause }
|
||||
{ run f5 }
|
||||
{ restart f5 ctrl shift }
|
||||
{ step_into f11 }
|
||||
{ step_over f10 }
|
||||
{ run_to_line f10 ctrl }
|
||||
{ set_next_statement f10 ctrl shift }
|
||||
{ inc_window_font_size equal alt }
|
||||
{ dec_window_font_size minus alt }
|
||||
{ window n ctrl shift }
|
||||
{ toggle_fullscreen return ctrl }
|
||||
{ new_panel_right p ctrl }
|
||||
{ new_panel_down minus ctrl }
|
||||
{ rotate_panel_columns 2 ctrl }
|
||||
{ next_panel comma ctrl }
|
||||
{ prev_panel comma ctrl shift }
|
||||
{ focus_panel_right right ctrl alt }
|
||||
{ focus_panel_left left ctrl alt }
|
||||
{ focus_panel_up up ctrl alt }
|
||||
{ focus_panel_down down ctrl alt }
|
||||
{ undo z ctrl }
|
||||
{ redo y ctrl }
|
||||
{ go_back left alt }
|
||||
{ go_forward right alt }
|
||||
{ close_panel p ctrl shift alt }
|
||||
{ next_tab page_down ctrl }
|
||||
{ prev_tab page_up ctrl }
|
||||
{ next_tab tab ctrl }
|
||||
{ prev_tab tab ctrl shift }
|
||||
{ move_tab_right page_down ctrl shift }
|
||||
{ move_tab_left page_up ctrl shift }
|
||||
{ close_tab w ctrl }
|
||||
{ tab_bar_top up ctrl shift alt }
|
||||
{ tab_bar_bottom down ctrl shift alt }
|
||||
{ open_tab t ctrl }
|
||||
{ open o ctrl }
|
||||
{ switch i ctrl }
|
||||
{ switch_to_partner_file o alt }
|
||||
{ open_user n ctrl shift alt }
|
||||
{ open_project n ctrl alt }
|
||||
{ open_user o ctrl shift alt }
|
||||
{ open_project o ctrl alt }
|
||||
{ save_user s ctrl shift alt }
|
||||
{ save_project s ctrl shift }
|
||||
{ edit f2 }
|
||||
{ accept return }
|
||||
{ accept space }
|
||||
{ cancel esc }
|
||||
{ move_left left }
|
||||
{ move_right right }
|
||||
{ move_up up }
|
||||
{ move_down down }
|
||||
{ move_left_select left shift }
|
||||
{ move_right_select right shift }
|
||||
{ move_up_select up shift }
|
||||
{ move_down_select down shift }
|
||||
{ move_left_chunk left ctrl }
|
||||
{ move_right_chunk right ctrl }
|
||||
{ move_up_chunk up ctrl }
|
||||
{ move_down_chunk down ctrl }
|
||||
{ move_up_page page_up }
|
||||
{ move_down_page page_down }
|
||||
{ move_up_whole home ctrl }
|
||||
{ move_down_whole end ctrl }
|
||||
{ move_left_chunk_select left ctrl shift }
|
||||
{ move_right_chunk_select right ctrl shift }
|
||||
{ move_up_chunk_select up ctrl shift }
|
||||
{ move_down_chunk_select down ctrl shift }
|
||||
{ move_up_page_select page_up shift }
|
||||
{ move_down_page_select page_down shift }
|
||||
{ move_up_whole_select home ctrl shift }
|
||||
{ move_down_whole_select end ctrl shift }
|
||||
{ move_up_reorder up alt }
|
||||
{ move_down_reorder down alt }
|
||||
{ move_home home }
|
||||
{ move_end end }
|
||||
{ move_home_select home shift }
|
||||
{ move_end_select end shift }
|
||||
{ select_all a ctrl }
|
||||
{ delete_single delete }
|
||||
{ delete_chunk delete ctrl }
|
||||
{ backspace_single backspace }
|
||||
{ backspace_chunk backspace ctrl }
|
||||
{ copy c ctrl }
|
||||
{ copy insert ctrl }
|
||||
{ cut x ctrl }
|
||||
{ paste v ctrl }
|
||||
{ paste insert shift }
|
||||
{ insert_text null }
|
||||
{ move_next tab }
|
||||
{ move_prev tab shift }
|
||||
{ goto_line g ctrl }
|
||||
{ goto_address g alt }
|
||||
{ search f ctrl }
|
||||
{ search_backwards r ctrl }
|
||||
{ find_next f3 }
|
||||
{ find_prev f3 ctrl }
|
||||
{ find_selected_thread f4 }
|
||||
{ goto_name j ctrl }
|
||||
{ goto_name_at_cursor f12 }
|
||||
{ toggle_watch_expr_at_cursor w alt }
|
||||
{ toggle_watch_expr_at_mouse d ctrl }
|
||||
{ toggle_watch_pin f9 ctrl }
|
||||
{ toggle_breakpoint f9 }
|
||||
{ add_address_breakpoint f9 shift }
|
||||
{ add_function_breakpoint f9 ctrl shift }
|
||||
{ attach f6 shift }
|
||||
{ open_palette f1 }
|
||||
{ open_palette p ctrl shift }
|
||||
{ log_marker m ctrl shift alt }
|
||||
{ toggle_dev_menu d ctrl shift alt }
|
||||
}
|
||||
current_path: "C:/projects/WATL_Exercise/build"
|
Reference in New Issue
Block a user