- PrettyPrinters working, added cstring/wcstring, string/wstring, optional, allocation, list

This commit is contained in:
2025-08-08 01:54:39 -04:00
parent 2cb41e1437
commit b7d8426e86
6 changed files with 158 additions and 72 deletions

View File

@@ -1 +1 @@
source fennec/gdb/printers.py source ./gdb/printers.py

View File

@@ -1,26 +0,0 @@
import sys
class ListPrinter:
"""Print a fennec::list"""
class Iterator:
def __init__(self, head):
self.node = head
def __iter__(self):
return self
def __next__(self):
if self.node == sys.maxsize:
raise StopIteration
value = self.node['*data']
self.node = self.node['_data[next]']
return value
def __init__(self, val):
self.val = val
def to_string(self):
return "fennec::list"
def children(self):
return enumerate(self.Iterator(self.val['_data[_root]']))

View File

@@ -1,9 +1,119 @@
import gdb
import sys
# CSTRING ==============================================================================================================
class CStringPrinter:
def __init__(self, val):
self.val = val
def to_string(self):
return self.val['_cstr']
def children(self):
size = int(self.val['_size'])
start = self.val['_cstr']
return (('[{}]'.format(i), start[i]) for i in range(size))
# ALLOCATION ===========================================================================================================
class StringPrinter:
def __init__(self, val):
self.val = val
def to_string(self):
return str("fennec::allocation = {value}").format(value = self.val['_str']['_data'])
def children(self):
size = int(self.val['_str']['_capacity'])
start = self.val['_str']['_data']
return (('[{}]'.format(i), start[i]) for i in range(size))
# OPTIONAL =================================================================================================================
class OptionalPrinter:
"""Print a fennec::optional"""
def __init__(self, val):
self.val = val
def to_string(self):
is_initialized = self.val['_set']
if is_initialized:
return "Value = {}".format(self.val['_val'])
else:
return "empty"
# ALLOCATION ===========================================================================================================
class AllocationPrinter:
def __init__(self, val):
self.val = val
def to_string(self):
return "fennec::allocation"
def children(self):
size = int(self.val['_capacity'])
start = self.val['_data']
return (('[{}]'.format(i), start[i]) for i in range(size))
# LIST =================================================================================================================
class ListPrinter:
"""Print a fennec::list"""
class Iterator:
def __init__(self, val):
self.list = val
self.node = self.list['_root']
#self.index = 0
def __iter__(self):
return self
def __next__(self):
if self.node == 18446744073709551615:
raise StopIteration
value = self.list['_table']['_data'][self.node]['value']['_val']
self.node = self.list['_table']['_data'][self.node]['next']
return value
#index = self.index
#self.index = self.index + 1
#value = self.list['_table']['_data'][self.node]['value']['_val']
#self.node = self.list['_table']['_data'][self.node]['next']
#return str("value[{index}] = {value}").format(index = index, value = value)
def __init__(self, val):
self.val = val
def to_string(self):
return "fennec::list"
def children(self):
return enumerate(self.Iterator(self.val))
# GDB CODE =============================================================================================================
from list import ListPrinter
def lookup_function(val): def lookup_function(val):
if str(val.type) == "fennec::list": type = str(val.type)
if type.startswith('const '):
type = type[6:]
if type.startswith('fennec::cstring') or type.startswith('fennec::wcstring'):
return CStringPrinter(val)
if type.startswith('fennec::string') or type.startswith('fennec::wstring'):
return StringPrinter(val)
if type.startswith('fennec::optional'):
return OptionalPrinter(val)
if type.startswith('fennec::list'):
return ListPrinter(val) return ListPrinter(val)
if type.startswith('fennec::allocation'):
return AllocationPrinter(val)
return None return None

View File

@@ -87,7 +87,7 @@ public:
/// \brief Destructor, destructs all elements then releases the allocation. /// \brief Destructor, destructs all elements then releases the allocation.
constexpr ~list() { constexpr ~list() {
for (size_t i = 0; i < capacity(); ++i) { for (size_t i = 0; i < capacity(); ++i) {
_table[i].data = nullopt; _table[i].value = nullopt;
} }
} }
@@ -119,7 +119,7 @@ public:
assertd(i >= 0 && size_t(i) < _size, "Index out of Bounds"); assertd(i >= 0 && size_t(i) < _size, "Index out of Bounds");
size_t n = _walk(i); size_t n = _walk(i);
assertd(n != npos, "Index out of Bounds"); assertd(n != npos, "Index out of Bounds");
return *_table[n].data; return *_table[n].value;
} }
/// ///
@@ -132,35 +132,35 @@ public:
assertd(i >= 0 && size_t(i) < _size, "Index out of Bounds"); assertd(i >= 0 && size_t(i) < _size, "Index out of Bounds");
size_t n = _walk(i); size_t n = _walk(i);
assertd(n != npos, "Index out of Bounds"); assertd(n != npos, "Index out of Bounds");
return *_table[n].data; return *_table[n].value;
} }
/// ///
/// \brief Access Front Element /// \brief Access Front Element
/// \returns A reference to the first element in the list /// \returns A reference to the first element in the list
constexpr value_t& front() { constexpr value_t& front() {
return *_table[_root].data; return *_table[_root].value;
} }
/// ///
/// \brief Const Access Front Element /// \brief Const Access Front Element
/// \returns A const-qualified reference to the first element in the list /// \returns A const-qualified reference to the first element in the list
constexpr const value_t& front() const { constexpr const value_t& front() const {
return *_table[_root].data; return *_table[_root].value;
} }
/// ///
/// \brief Access Back Element /// \brief Access Back Element
/// \returns A reference to the last element in the list /// \returns A reference to the last element in the list
constexpr value_t& back() { constexpr value_t& back() {
return *_table[_last].data; return *_table[_last].value;
} }
/// ///
/// \brief Const Access Back Element /// \brief Const Access Back Element
/// \returns A const-qualified reference to the last element in the list /// \returns A const-qualified reference to the last element in the list
constexpr const value_t& back() const { constexpr const value_t& back() const {
return *_table[_last].data; return *_table[_last].value;
} }
@@ -327,11 +327,11 @@ public:
} }
constexpr value_t& operator*() { constexpr value_t& operator*() {
return *(_list->_table[_n].data); return *(_list->_table[_n].value);
} }
constexpr value_t* operator->() { constexpr value_t* operator->() {
return &*(_list->_table[_n].data); return &*(_list->_table[_n].value);
} }
constexpr bool operator==(const iterator& it) { constexpr bool operator==(const iterator& it) {
@@ -377,11 +377,11 @@ public:
} }
constexpr const value_t& operator*() { constexpr const value_t& operator*() {
return *(_list->_table[_n].data); return *(_list->_table[_n].value);
} }
constexpr const value_t* operator->() { constexpr const value_t* operator->() {
return &*(_list->_table[_n].data); return &*(_list->_table[_n].value);
} }
constexpr bool operator==(const const_iterator& it) { constexpr bool operator==(const const_iterator& it) {
@@ -439,23 +439,23 @@ private:
} }
struct node { struct node {
optional<value_t> data; optional<value_t> value;
size_t prev, next; size_t prev, next;
constexpr node() constexpr node()
: data() : value()
, prev(npos) , prev(npos)
, next(npos) { , next(npos) {
} }
constexpr node(size_t p, size_t n) constexpr node(size_t p, size_t n)
: data() : value()
, prev(p) , prev(p)
, next(n) { , next(n) {
} }
constexpr node(size_t p, size_t n, value_t&& val) constexpr node(size_t p, size_t n, value_t&& val)
: data(fennec::forward<value_t>(val)) : value(fennec::forward<value_t>(val))
, prev(p) , prev(p)
, next(n) { , next(n) {
} }
@@ -463,7 +463,7 @@ private:
constexpr ~node() = default; constexpr ~node() = default;
constexpr void clear() { constexpr void clear() {
data = nullopt; value = nullopt;
prev = npos; prev = npos;
next = npos; next = npos;
} }
@@ -503,7 +503,7 @@ private:
size_t i = _next_free(); size_t i = _next_free();
++_size; ++_size;
fennec::construct(&_table[i].data, fennec::forward<ArgsT>(args)...); fennec::construct(&_table[i].value, fennec::forward<ArgsT>(args)...);
if (_root == npos) { if (_root == npos) {
_table[i].prev = npos; _table[i].prev = npos;
@@ -530,7 +530,7 @@ private:
constexpr void _erase(size_t n) { constexpr void _erase(size_t n) {
if (n == npos) return; if (n == npos) return;
fennec::destruct(&_table[n].data); fennec::destruct(&_table[n].value);
_freed.push_back(n); _freed.push_back(n);
--_size; --_size;

View File

@@ -68,37 +68,37 @@ public:
template<typename...ArgsT> template<typename...ArgsT>
explicit constexpr rdtree(ArgsT&&...args) explicit constexpr rdtree(ArgsT&&...args)
: _data(), _freed(), _size(1) { : _table(), _freed(), _size(1) {
_data.callocate(8); _table.callocate(8);
fennec::construct(&_data[0], npos, npos, npos, npos, fennec::forward<ArgsT>(args)...); fennec::construct(&_table[0], npos, npos, npos, npos, fennec::forward<ArgsT>(args)...);
} }
constexpr rdtree(const rdtree& tree) constexpr rdtree(const rdtree& tree)
: _data(tree._data), _freed(tree._freed), _size(tree._size) { : _table(tree._table), _freed(tree._freed), _size(tree._size) {
} }
constexpr rdtree(rdtree&& tree) noexcept constexpr rdtree(rdtree&& tree) noexcept
: _data(fennec::move(tree._data)), _freed(fennec::move(tree._freed)), _size(tree._size) { : _table(fennec::move(tree._table)), _freed(fennec::move(tree._freed)), _size(tree._size) {
} }
// Assignment ========================================================================================================== // Assignment ==========================================================================================================
constexpr rdtree& operator=(const rdtree& rhs) { constexpr rdtree& operator=(const rdtree& rhs) {
for (value_t* it : this->_data) { for (value_t* it : this->_table) {
fennec::destruct(it); fennec::destruct(it);
} }
_data = rhs._data; _table = rhs._table;
_freed = rhs._freed; _freed = rhs._freed;
_size = rhs._size; _size = rhs._size;
return *this; return *this;
} }
constexpr rdtree& operator=(rdtree&& rhs) noexcept { constexpr rdtree& operator=(rdtree&& rhs) noexcept {
for (value_t* it : _data) { for (value_t* it : _table) {
fennec::destruct(it); fennec::destruct(it);
} }
_data = fennec::move(rhs._data); _table = fennec::move(rhs._table);
_freed = fennec::move(rhs._freed); _freed = fennec::move(rhs._freed);
_size = rhs._size; _size = rhs._size;
return *this; return *this;
@@ -112,7 +112,7 @@ public:
} }
constexpr size_t capacity() const { constexpr size_t capacity() const {
return _data.capacity(); return _table.capacity();
} }
constexpr bool empty() const { constexpr bool empty() const {
@@ -126,42 +126,42 @@ public:
/// \param i The id of the node to check /// \param i The id of the node to check
/// \returns The id of the parent node /// \returns The id of the parent node
constexpr size_t parent(size_t i) const { constexpr size_t parent(size_t i) const {
return i == npos ? npos : _data[i].parent; return i == npos ? npos : _table[i].parent;
} }
/// ///
/// \param i The id of the node to check /// \param i The id of the node to check
/// \returns The id of the child node /// \returns The id of the child node
constexpr size_t child(size_t i) const { constexpr size_t child(size_t i) const {
return i == npos ? npos : _data[i].child; return i == npos ? npos : _table[i].child;
} }
/// ///
/// \param i The id of the node to check /// \param i The id of the node to check
/// \returns The id of the next node /// \returns The id of the next node
constexpr size_t next(size_t i) const { constexpr size_t next(size_t i) const {
return i == npos ? npos : _data[i].next; return i == npos ? npos : _table[i].next;
} }
/// ///
/// \param i The id of the node to check /// \param i The id of the node to check
/// \returns The id of the previous node /// \returns The id of the previous node
constexpr size_t prev(size_t i) const { constexpr size_t prev(size_t i) const {
return i == npos ? npos : _data[i].prev; return i == npos ? npos : _table[i].prev;
} }
/// ///
/// \param i The id of the node to access /// \param i The id of the node to access
/// \returns A reference to the value of the node wrapped in an optional /// \returns A reference to the value of the node wrapped in an optional
constexpr optional<value_t>& operator[](size_t i) { constexpr optional<value_t>& operator[](size_t i) {
return _data[i].value; return _table[i].value;
} }
/// ///
/// \param i The id of the node to access /// \param i The id of the node to access
/// \returns A const-qualified reference to the value of the node wrapped in an optional /// \returns A const-qualified reference to the value of the node wrapped in an optional
constexpr const optional<value_t>& operator[](size_t i) const { constexpr const optional<value_t>& operator[](size_t i) const {
return _data[i].value; return _table[i].value;
} }
@@ -194,12 +194,12 @@ public:
protected: protected:
allocation<node, alloc_t> _data; allocation<node, alloc_t> _table;
list<size_t> _freed; list<size_t> _freed;
size_t _size; size_t _size;
void _expand() { void _expand() {
_data.creallocate(_data.capacity() * 2); _table.creallocate(_table.capacity() * 2);
} }
size_t _next_free() { size_t _next_free() {
@@ -217,21 +217,21 @@ protected:
template<typename...ArgsT> template<typename...ArgsT>
constexpr size_t _insert(size_t p, ArgsT&&...args) { constexpr size_t _insert(size_t p, ArgsT&&...args) {
if (_size == 0) { if (_size == 0) {
fennec::construct(&_data[root], npos, npos, npos, npos, fennec::forward<ArgsT>(args)...); fennec::construct(&_table[root], npos, npos, npos, npos, fennec::forward<ArgsT>(args)...);
_size = 1; _size = 1;
return root; return root;
} }
if (p == npos) { if (p == npos) {
_data[root].value = value_t(fennec::forward<ArgsT>(args)...); _table[root].value = value_t(fennec::forward<ArgsT>(args)...);
return root; return root;
} }
size_t i = _next_free(); size_t i = _next_free();
size_t n = child(p); size_t n = child(p);
_data[p].child = i; _table[p].child = i;
if (n != npos) _data[n].prev = i; if (n != npos) _table[n].prev = i;
fennec::construct(&_data[i], p, npos, npos, n, fennec::forward<ArgsT>(args)...); fennec::construct(&_table[i], p, npos, npos, n, fennec::forward<ArgsT>(args)...);
return i; return i;
} }
@@ -244,13 +244,13 @@ protected:
if (n == npos) continue; if (n == npos) continue;
queue.push_back(next(n)); queue.push_back(next(n));
queue.push_back(child(n)); queue.push_back(child(n));
fennec::destruct(&_data[n]); fennec::destruct(&_table[n]);
_freed.push_back(n); _freed.push_back(n);
--_size; --_size;
++j; ++j;
} }
fennec::destruct(&_data[i]); fennec::destruct(&_table[i]);
_freed.push_back(i); _freed.push_back(i);
--_size; --_size;
} }

View File

@@ -19,6 +19,8 @@
#ifndef FENNEC_TEST_LANGPROC_STRINGS_CSTRING_H #ifndef FENNEC_TEST_LANGPROC_STRINGS_CSTRING_H
#define FENNEC_TEST_LANGPROC_STRINGS_CSTRING_H #define FENNEC_TEST_LANGPROC_STRINGS_CSTRING_H
#include "../../../test.h"
#include <fennec/langproc/strings/cstring.h> #include <fennec/langproc/strings/cstring.h>
namespace fennec::test namespace fennec::test