122 lines
2.8 KiB
C
122 lines
2.8 KiB
C
////////////////////////////////
|
|
// Typical Base Stuff
|
|
|
|
static B32
|
|
str8_match(String8 a, String8 b){
|
|
B32 result = 0;
|
|
if (a.size == b.size){
|
|
result = 1;
|
|
for (U64 i = 0; i < a.size; i += 1){
|
|
if (a.str[i] != b.str[i]){
|
|
result = 0;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return(result);
|
|
}
|
|
|
|
static Arena
|
|
arena_alloc(U64 cap){
|
|
Arena arena = {0};
|
|
arena.memory = malloc(cap);
|
|
arena.cap = cap;
|
|
return(arena);
|
|
}
|
|
|
|
static void*
|
|
arena_push(Arena *arena, U64 size){
|
|
void *result = 0;
|
|
if (arena->pos + size <= arena->cap){
|
|
result = (U8*)arena->memory + arena->pos;
|
|
arena->pos += size;
|
|
arena->pos = (arena->pos + 7)&~7; // "round up to multiple of 8"
|
|
memset(result, 0, size);
|
|
}
|
|
return(result);
|
|
}
|
|
|
|
static void
|
|
arena_pop_to(Arena *arena, U64 pos){
|
|
if (pos < arena->pos){
|
|
arena->pos = (pos + 7)&~7; // "round up to multiple of 8"
|
|
}
|
|
}
|
|
|
|
static void
|
|
arena_pop_amount(Arena *arena, U64 amount){
|
|
U64 pos = arena->pos;
|
|
U64 new_pos = 0;
|
|
if (pos > amount){
|
|
new_pos = pos - amount;
|
|
}
|
|
arena_pop_to(arena, new_pos);
|
|
}
|
|
|
|
static U64
|
|
arena_pos(Arena *arena){
|
|
return(arena->pos);
|
|
}
|
|
|
|
static String8
|
|
str8_pushfv(Arena *arena, char *fmt, va_list args){
|
|
// in case we need to try a second time
|
|
va_list args2;
|
|
va_copy(args2, args);
|
|
|
|
// try to build the string in 1024 bytes
|
|
U64 buffer_size = 1024;
|
|
U8 *buffer = push_array(arena, U8, buffer_size);
|
|
U64 actual_size = vsnprintf((char*)buffer, buffer_size, fmt, args);
|
|
|
|
String8 result = {0};
|
|
if (actual_size < buffer_size){
|
|
// if first try worked, put back what we didn't use and finish
|
|
arena_pop_amount(arena, buffer_size - actual_size - 1);
|
|
result = (String8){buffer, actual_size};
|
|
}
|
|
else{
|
|
// if first try failed, reset and try again with correct size
|
|
arena_pop_amount(arena, buffer_size);
|
|
U8 *fixed_buffer = push_array(arena, U8, actual_size + 1);
|
|
U64 final_size = vsnprintf((char*)fixed_buffer, actual_size + 1, fmt, args2);
|
|
result = (String8){fixed_buffer, final_size};
|
|
}
|
|
|
|
// end args2
|
|
va_end(args2);
|
|
|
|
return(result);
|
|
}
|
|
|
|
////////////////////////////////
|
|
// Symbol-Set Specific Upgrades
|
|
|
|
static void*
|
|
copy_strided(void *dst, U32 dst_stride,
|
|
void *src, U32 src_stride,
|
|
U32 count){
|
|
void *base_src = src;
|
|
void *base_dst = dst;
|
|
if (dst_stride != src_stride){
|
|
U32 size = Min(dst_stride, src_stride);
|
|
for (U32 i = 0; i < count; i += 1){
|
|
memcpy(dst, src, size);
|
|
dst = (U8*)dst + dst_stride;
|
|
src = (U8*)src + src_stride;
|
|
}
|
|
}
|
|
else{
|
|
memcpy(dst, src, dst_stride*count);
|
|
}
|
|
return(base_dst);
|
|
}
|
|
|
|
static void*
|
|
arena_push_symbol_set__raw(Arena *arena,
|
|
U32 size, void *src, U32 src_stride, U32 count){
|
|
void *dst = push_array(arena, U8, size*(count + 1));
|
|
copy_strided((U8*)dst + size, size, src, src_stride, count);
|
|
return(dst);
|
|
}
|