#ifndef SOURCE_CC #define SOURCE_CC #include "array.cc" #include "common.cc" #include "memory.cc" typedef u32 Source_Id; struct Span { Source_Id id; usize start, end; Span(Source_Id id, usize start, usize end) : id(id), start(start), end(end) {} }; struct Buffer { String file; String content; Link link; const Allocator* allocator; }; bool buffer_init(Buffer* buffer, const Allocator* allocator, const String* content_in, const String* file_in) { assert_neq(buffer, nullptr); assert_neq(allocator, nullptr); assert_neq(content_in, nullptr); assert_neq(file_in, nullptr); String content, file; bool ret = slice_copy(allocator, content_in, &content); if (unlikely(!ret)) return false; ret = slice_copy(allocator, file_in, &file); if (unlikely(!ret)) { slice_deallocate(allocator, &content); return false; } buffer->file = file; buffer->content = content; buffer->allocator = allocator; buffer->link = {}; return true; } void buffer_deinit(Buffer* buffer) { assert_neq(buffer, nullptr); slice_deallocate(buffer->allocator, &buffer->file); slice_deallocate(buffer->allocator, &buffer->content); memset(buffer, 0, sizeof(*buffer)); } struct Buffer_Manager { Link* stack; Array buffers; }; #define buffer_manager_init(allocator) \ Buffer_Manager { nullptr, array_init(Buffer, allocator) } bool buffer_manager_push(Buffer_Manager* manager, Buffer* b) { assert_neq(manager, nullptr); assert_neq(b, nullptr); bool ret = array_push(&manager->buffers, b); if(!ret) return false; b = array_last(&manager->buffers); if(manager->stack == nullptr) { manager->stack = &b->link; return true; } link_after(manager->stack, &b->link); return true; } void buffer_manager_deinit(Buffer_Manager* manager) { assert_neq(manager, nullptr); array_deinit(&manager->buffers); } #endif