#ifndef SOURCE_CC #define SOURCE_CC #include #include "common.cc" #include "memory.cc" struct Span { String file; usize start, end; Span() : file(), start(0), end(0) {} Span(String file, usize start, usize end) : file(file), start(start), end(end) {} }; bool span_write(const Span* span, FILE* stream) { assert_neq(span, nullptr); assert_neq(stream, nullptr); i32 rc = fprintf(stream, "Span { file: "); if (unlikely(rc < 0)) return false; bool status = string_write(&span->file, stream); if (unlikely(!status)) return false; rc = fprintf(stream, ", start: %zu, end: %zu }", span->start, span->end); if (unlikely(rc < 0)) return false; return true; } 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); // TODO: use defer!! 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(allocator, (u8*)buffer); } struct Buffer_Stack { Link* stack; }; void buffer_stack_push(Buffer_Stack* stack, Buffer* b) { assert_neq(stack, nullptr); assert_neq(b, nullptr); if (likely(stack->stack != nullptr)) link_after(stack->stack, &b->link); stack->stack = &b->link; } bool buffer_stack_pop(Buffer_Stack* stack, Buffer** b) { assert_neq(stack, nullptr); assert_neq(b, nullptr); Link* link = stack->stack; if (unlikely(link == nullptr)) return false; Link* next = link->prev; link_remove(link); stack->stack = next; Buffer* buffer = containerof(Buffer, link, link); *b = buffer; return true; } #endif