#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(const Allocator* allocator, const String* content_in, const String* file_in, Buffer** out) { assert_neq(allocator, nullptr); assert_neq(content_in, nullptr); assert_neq(file_in, nullptr); assert_neq(out, nullptr); Buffer* buffer = allocate(allocator, 1); if(buffer == nullptr) return false; String content, file; bool ret = slice_copy(allocator, content_in, &content); if (unlikely(!ret)) { deallocate(allocator, (u8*)buffer); return false; } ret = slice_copy(allocator, file_in, &file); if (unlikely(!ret)) { slice_deallocate(allocator, &content); deallocate(allocator, (u8*)buffer); return false; } buffer->file = file; buffer->content = content; buffer->allocator = allocator; buffer->link = {}; *out = buffer; return true; } void buffer_deinit(Buffer* buffer) { assert_neq(buffer, nullptr); const Allocator* allocator = buffer->allocator; if(allocator == nullptr) return; slice_deallocate(buffer->allocator, &buffer->file); slice_deallocate(buffer->allocator, &buffer->content); memset(buffer, 0, sizeof(*buffer)); deallocate(buffer->allocator, (u8*)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) link_after(manager->stack, &b->link); manager->stack = &b->link; return true; } bool buffer_manager_pop(Buffer_Manager* manager, Buffer** b) { assert_neq(manager, nullptr); assert_neq(b, nullptr); Link* link = manager->stack; if (link == nullptr) return false; Link* next = link->prev; link_remove(link); manager->stack = next; Buffer* buffer = containerof(Buffer, link, link); *b = buffer; return true; } void buffer_manager_deinit(Buffer_Manager* manager) { assert_neq(manager, nullptr); array_deinit(&manager->buffers); } #endif