//////////////////////////////// // 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); }