#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; usize cursor; }; 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; memset(buffer, 0, sizeof(*buffer)); 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; *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_Stack { Link* stack; }; void buffer_stack_push(Buffer_Stack* manager, Buffer* b) { assert_neq(manager, nullptr); assert_neq(b, nullptr); if (manager->stack != nullptr) link_after(manager->stack, &b->link); manager->stack = &b->link; } bool buffer_stack_pop(Buffer_Stack* 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; } #endif