BAN: Move Formatter to new project called BAN
I also implemented basic ErrorOr and Queue
This commit is contained in:
		
							parent
							
								
									1283e74ee6
								
							
						
					
					
						commit
						835430e7b0
					
				|  | @ -0,0 +1,86 @@ | ||||||
|  | DEFAULT_HOST!=../default-host.sh | ||||||
|  | HOST?=DEFAULT_HOST | ||||||
|  | HOSTARCH!=../target-triplet-to-arch.sh $(HOST) | ||||||
|  |   | ||||||
|  | CFLAGS?=-O2 -g | ||||||
|  | CPPFLAGS?= | ||||||
|  | LDFLAGS?= | ||||||
|  | LIBS?= | ||||||
|  |   | ||||||
|  | DESTDIR?= | ||||||
|  | PREFIX?=/usr/local | ||||||
|  | EXEC_PREFIX?=$(PREFIX) | ||||||
|  | INCLUDEDIR?=$(PREFIX)/include | ||||||
|  | LIBDIR?=$(EXEC_PREFIX)/lib | ||||||
|  |   | ||||||
|  | CFLAGS:=$(CFLAGS) -D__is_ban -Iinclude -ffreestanding -Wall -Wextra | ||||||
|  | CPPFLAGS:=$(CPPFLAGS) | ||||||
|  | LIBK_CFLAGS:=$(CFLAGS) -D__is_bank | ||||||
|  | LIBK_CPPFLAGS:=$(CPPFLAGS) | ||||||
|  |   | ||||||
|  | ARCHDIR=arch/$(HOSTARCH) | ||||||
|  |   | ||||||
|  | include $(ARCHDIR)/make.config | ||||||
|  |   | ||||||
|  | CFLAGS:=$(CFLAGS) $(ARCH_CFLAGS) | ||||||
|  | CPPFLAGS:=$(CPPFLAGS) $(ARCH_CPPFLAGS) | ||||||
|  | BANK_CFLAGS:=$(BANK_CFLAGS) $(KERNEL_ARCH_CFLAGS) | ||||||
|  | BANK_CPPFLAGS:=$(BANK_CPPFLAGS) $(KERNEL_ARCH_CPPFLAGS) | ||||||
|  |   | ||||||
|  | BUILDDIR=$(abspath build) | ||||||
|  |   | ||||||
|  | FREEOBJS=\
 | ||||||
|  | $(ARCH_FREEOBJS) \ | ||||||
|  |   | ||||||
|  | HOSTEDOBJS=\
 | ||||||
|  | $(ARCH_HOSTEDOBJS) \ | ||||||
|  |   | ||||||
|  | OBJS=\
 | ||||||
|  | $(FREEOBJS) \ | ||||||
|  | $(HOSTEDOBJS) \ | ||||||
|  |   | ||||||
|  | BANK_OBJS=$(FREEOBJS:.o=.bank.o) | ||||||
|  |   | ||||||
|  | BINARIES=bank.a | ||||||
|  |   | ||||||
|  | .PHONY: all always clean install install-headers install-libs | ||||||
|  | .SUFFIXES: .o .bank.o .cpp .S | ||||||
|  |   | ||||||
|  | all: $(BINARIES) | ||||||
|  |   | ||||||
|  | ban.a: always $(OBJS) | ||||||
|  | 	cd $(BUILDDIR) && $(AR) rcs $@ $(OBJS) | ||||||
|  |   | ||||||
|  | bank.a: always $(LIBK_OBJS) | ||||||
|  | 	cd $(BUILDDIR) && $(AR) rcs $@ $(LIBK_OBJS) | ||||||
|  |   | ||||||
|  | .cpp.o: | ||||||
|  | 	$(CXX) -MD -c $< -o $(BUILDDIR)/$@ $(CFLAGS) $(CPPFLAGS) | ||||||
|  |   | ||||||
|  | .S.o: | ||||||
|  | 	$(CXX) -MD -c $< -o $(BUILDDIR)/$@ $(CFLAGS) $(CPPFLAGS) | ||||||
|  |   | ||||||
|  | .cpp.bank.o: | ||||||
|  | 	$(CXX) -MD -c $< -o $(BUILDDIR)/$@ $(LIBK_CFLAGS) $(LIBK_CPPFLAGS) | ||||||
|  |   | ||||||
|  | .S.bank.o: | ||||||
|  | 	$(CXX) -MD -c $< -o $(BUILDDIR)/$@ $(LIBK_CFLAGS) $(LIBK_CPPFLAGS) | ||||||
|  |   | ||||||
|  | clean: | ||||||
|  | 	rm -rf $(BUILDDIR) | ||||||
|  |   | ||||||
|  | always: | ||||||
|  | 	mkdir -p $(BUILDDIR) | ||||||
|  |   | ||||||
|  | install: install-headers install-libs | ||||||
|  |   | ||||||
|  | install-headers: | ||||||
|  | 	mkdir -p $(DESTDIR)$(INCLUDEDIR) | ||||||
|  | 	cp -R --preserve=timestamps include/. $(DESTDIR)$(INCLUDEDIR)/. | ||||||
|  |   | ||||||
|  | install-libs: $(BINARIES) | ||||||
|  | 	mkdir -p $(DESTDIR)$(LIBDIR) | ||||||
|  | 	cp $(BUILDDIR)/$(BINARIES) $(DESTDIR)$(LIBDIR) | ||||||
|  |   | ||||||
|  | -include $(OBJS:.o=.d) | ||||||
|  | -include $(LIBK_OBJS:.o=.d) | ||||||
|  | @ -0,0 +1,8 @@ | ||||||
|  | ARCH_CFLAGS= | ||||||
|  | ARCH_CPPFLAGS= | ||||||
|  | KERNEL_ARCH_CFLAGS= | ||||||
|  | KERNEL_ARCH_CPPFLAGS= | ||||||
|  |   | ||||||
|  | ARCH_FREEOBJS=\ | ||||||
|  |   | ||||||
|  | ARCH_HOSTEDOBJS=\ | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | !<arch> | ||||||
|  | @ -0,0 +1,78 @@ | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <BAN/Formatter.h> | ||||||
|  | 
 | ||||||
|  | #if defined(__is_bank) | ||||||
|  | 	#include <kernel/panic.h> | ||||||
|  | 	#define MUST(error)	{ decltype(error) e = error; if (e.HasError()) { Kernel::panic("{}", e.GetError()); } } | ||||||
|  | #else | ||||||
|  | 	#error "NOT IMPLEMENTED" | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #define TRY(error)	{ decltype(error) e = error; if (e.HasError()) return e; } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Error | ||||||
|  | { | ||||||
|  | public: | ||||||
|  | 	static Error FromString(const char* message) | ||||||
|  | 	{ | ||||||
|  | 		Error result; | ||||||
|  | 		strncpy(result.m_message, message, sizeof(m_message)); | ||||||
|  | 		result.m_message[sizeof(result.m_message) - 1] = '\0'; | ||||||
|  | 		result.m_error_code = 0xFF; | ||||||
|  | 		return result; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	uint8_t GetErrorCode() const { return m_error_code; } | ||||||
|  | 	const char* GetMessage() const { return m_message; } | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  | 	char m_message[128]; | ||||||
|  | 	uint8_t m_error_code; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | template<typename T> | ||||||
|  | class ErrorOr | ||||||
|  | { | ||||||
|  | public: | ||||||
|  | 	ErrorOr(const T& value)		: m_has_error(false)	{ m_data = (void*)new T(value); } | ||||||
|  | 	ErrorOr(const Error& error) : m_has_error(true)		{ m_data = (void*)new Error(error); } | ||||||
|  | 	~ErrorOr()											{ IsError() ? (delete reinterpret_cast<Error*>(m_data)) : (delete reinterpret_cast<T*>(m_data)); } | ||||||
|  | 
 | ||||||
|  | 	bool IsError() const			{ return m_has_error; } | ||||||
|  | 	const Error& GetError() const	{ return *reinterpret_cast<Error*>(m_data); } | ||||||
|  | 	T& Value()						{ return *reinterpret_cast<T*>(m_data); } | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  | 	bool	m_has_error; | ||||||
|  | 	void*	m_data; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | template<> | ||||||
|  | class ErrorOr<void> | ||||||
|  | { | ||||||
|  | public: | ||||||
|  | 	ErrorOr() : m_error(nullptr)	{ } | ||||||
|  | 	ErrorOr(const Error& error)		{ m_error = new Error(error); } | ||||||
|  | 	~ErrorOr()						{ delete m_error; } | ||||||
|  | 
 | ||||||
|  | 	bool IsError() const			{ return m_error; } | ||||||
|  | 	const Error& GetError() const	{ return *m_error; } | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  | 	Error*	m_error; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | namespace BAN::Formatter | ||||||
|  | { | ||||||
|  | 	template<void(*PUTC_LIKE)(char)> | ||||||
|  | 	void print_value(const Error& error, const ValueFormat& format) | ||||||
|  | 	{ | ||||||
|  | 		if (error.GetErrorCode() == 0xFF) | ||||||
|  | 			print<PUTC_LIKE>(error.GetMessage()); | ||||||
|  | 		else | ||||||
|  | 			print<PUTC_LIKE>("{} ({})", error.GetMessage(), error.GetErrorCode()); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -3,7 +3,7 @@ | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| #include <stddef.h> | #include <stddef.h> | ||||||
| 
 | 
 | ||||||
| namespace Formatter | namespace BAN::Formatter | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| 	struct ValueFormat; | 	struct ValueFormat; | ||||||
|  | @ -0,0 +1,125 @@ | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <BAN/Errors.h> | ||||||
|  | #include <kernel/kmalloc.h> | ||||||
|  | 
 | ||||||
|  | #if defined(__is_bank) | ||||||
|  | 	#include <kernel/kmalloc.h> | ||||||
|  | #else | ||||||
|  | 	#include <stdlib.h> | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #include <assert.h> | ||||||
|  | #include <stdint.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <sys/param.h> | ||||||
|  | 
 | ||||||
|  | namespace BAN | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | 	template<typename T> | ||||||
|  | 	class Queue | ||||||
|  | 	{ | ||||||
|  | 	private: | ||||||
|  | 	#if defined(__is_bank) | ||||||
|  | 		using allocator = kmalloc; | ||||||
|  | 		using deallocator = kfree; | ||||||
|  | 	#else | ||||||
|  | 		using allocator = malloc; | ||||||
|  | 		using deallocator = free; | ||||||
|  | 	#endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 	public: | ||||||
|  | 		using size_type = uint32_t; | ||||||
|  | 		using value_type = T; | ||||||
|  | 
 | ||||||
|  | 	public: | ||||||
|  | 		Queue() = default; | ||||||
|  | 		~Queue(); | ||||||
|  | 
 | ||||||
|  | 		ErrorOr<void> Push(const T& value); | ||||||
|  | 		void Pop(); | ||||||
|  | 
 | ||||||
|  | 		bool Empty() const; | ||||||
|  | 		size_type Size() const; | ||||||
|  | 
 | ||||||
|  | 		const T& Front() const; | ||||||
|  | 		T& Front(); | ||||||
|  | 
 | ||||||
|  | 	private: | ||||||
|  | 		ErrorOr<void> VerifyCapacity(size_type size); | ||||||
|  | 
 | ||||||
|  | 	private: | ||||||
|  | 		T*			m_data		= nullptr; | ||||||
|  | 		size_type	m_capacity	= 0; | ||||||
|  | 		size_type	m_size		= 0; | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	template<typename T> | ||||||
|  | 	Queue<T>::~Queue() | ||||||
|  | 	{ | ||||||
|  | 		deallocator(m_data); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	template<typename T> | ||||||
|  | 	ErrorOr<void> Queue<T>::Push(const T& value) | ||||||
|  | 	{ | ||||||
|  | 		VerifyCapacity(m_size + 1); | ||||||
|  | 		m_data[m_size++] = value; | ||||||
|  | 		return {}; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	template<typename T> | ||||||
|  | 	void Queue<T>::Pop() | ||||||
|  | 	{ | ||||||
|  | 		assert(m_size > 0); | ||||||
|  | 		m_data->~T(); | ||||||
|  | 		memmove(m_data, m_data + 1, sizeof(T) * (--m_size)); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	template<typename T> | ||||||
|  | 	bool Queue<T>::Empty() const | ||||||
|  | 	{ | ||||||
|  | 		return m_size == 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	template<typename T> | ||||||
|  | 	typename Queue<T>::size_type Queue<T>::Size() const | ||||||
|  | 	{ | ||||||
|  | 		return m_size; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	template<typename T> | ||||||
|  | 	const T& Queue<T>::Front() const | ||||||
|  | 	{ | ||||||
|  | 		assert(m_size > 0); | ||||||
|  | 		return *m_data; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	template<typename T> | ||||||
|  | 	T& Queue<T>::Front() | ||||||
|  | 	{ | ||||||
|  | 		assert(m_size > 0); | ||||||
|  | 		return *m_data; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	template<typename T> | ||||||
|  | 	ErrorOr<void> Queue<T>::VerifyCapacity(size_type size) | ||||||
|  | 	{ | ||||||
|  | 		if (m_capacity > size) | ||||||
|  | 			return {}; | ||||||
|  | 
 | ||||||
|  | 		size_type new_cap = MAX(m_capacity * 1.5f, m_capacity + 1) * sizeof(T); | ||||||
|  | 		void* new_data = allocator(new_cap); | ||||||
|  | 		if (new_data == nullptr) | ||||||
|  | 			return Error { .message = "Queue: out of memory", .error_code = ErrorCode::OutOfMemory }; | ||||||
|  | 
 | ||||||
|  | 		memcpy(new_data, m_data, m_size * sizeof(T)); | ||||||
|  | 		deallocator(m_data); | ||||||
|  | 
 | ||||||
|  | 		m_data = (T*)new_data; | ||||||
|  | 		m_capacity = new_cap; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| SYSTEM_HEADER_PROJECTS="libc kernel" | SYSTEM_HEADER_PROJECTS="libc BAN kernel" | ||||||
| PROJECTS="libc kernel" | PROJECTS="libc BAN kernel" | ||||||
|   |   | ||||||
| export MAKE=${MAKE:-make} | export MAKE=${MAKE:-make} | ||||||
| export HOST=${HOST:-$(./default-host.sh)} | export HOST=${HOST:-$(./default-host.sh)} | ||||||
|  |  | ||||||
|  | @ -1,9 +1,9 @@ | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include <kernel/Formatter.h> | #include <BAN/Formatter.h> | ||||||
| 
 | 
 | ||||||
| #define dprint		Formatter::print<Serial::serial_putc> | #define dprint		BAN::Formatter::print<Serial::serial_putc> | ||||||
| #define dprintln	Formatter::println<Serial::serial_putc> | #define dprintln	BAN::Formatter::println<Serial::serial_putc> | ||||||
| 
 | 
 | ||||||
| namespace Serial | namespace Serial | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include <kernel/Formatter.h> | #include <BAN/Formatter.h> | ||||||
| #include <kernel/tty.h> | #include <kernel/tty.h> | ||||||
| 
 | 
 | ||||||
| #define kprint		Formatter::print<TTY::putchar> | #define kprint		BAN::Formatter::print<TTY::putchar> | ||||||
| #define kprintln	Formatter::println<TTY::putchar> | #define kprintln	BAN::Formatter::println<TTY::putchar> | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue