- Adjusted some tests while debugging PrettyPrinters
- Adjusted RDTreePrinter to print more "tree-like" - Added SetPrinter and MapPrinter - Fixed Issues with CStringPrinter and StringPrinter
This commit is contained in:
4
.gdbinit
4
.gdbinit
@@ -1,7 +1,7 @@
|
||||
python
|
||||
import sys, os.path
|
||||
print(os.path.abspath("./gdbpp"))
|
||||
sys.path.insert(0, os.path.abspath("./gdbpp"))
|
||||
print(os.path.abspath("./gdb"))
|
||||
sys.path.insert(0, os.path.abspath("./gdb"))
|
||||
import fennec
|
||||
fennec.register_printers(gdb.current_objfile())
|
||||
end
|
||||
@@ -20,7 +20,12 @@
|
||||
# GDB CODE =============================================================================================================
|
||||
|
||||
import gdb
|
||||
from .containers import *
|
||||
|
||||
from . import containers
|
||||
from . import strings
|
||||
from . import memory
|
||||
|
||||
def register_printers(obj):
|
||||
gdb.printing.register_pretty_printer(obj, containers.printer)
|
||||
gdb.printing.register_pretty_printer(obj, strings.printer)
|
||||
gdb.printing.register_pretty_printer(obj, memory.printer)
|
||||
@@ -121,7 +121,7 @@ class ListPrinter:
|
||||
class RDTreePrinter:
|
||||
"""Print a fennec::rdtree"""
|
||||
|
||||
class Iterator: # TODO: Revisit, this is the best I could manage as my first attempt
|
||||
class Iterator:
|
||||
def __init__(self, tree, node, capacity):
|
||||
self.tree = tree
|
||||
self.capacity = capacity
|
||||
@@ -151,7 +151,7 @@ class RDTreePrinter:
|
||||
nprevc = self.tree[nprev]['child'] if nprev != 18446744073709551615 else 18446744073709551615
|
||||
child = self.tree[node]['child']
|
||||
|
||||
index = '⠀' * depth * 2
|
||||
index = '⠀' * depth * 2 # Uses Braille Space, otherwise it would get eaten as whitespace by parsers
|
||||
|
||||
if nnext < self.capacity:
|
||||
self.visit.appendleft((nnext, i + 1, depth))
|
||||
@@ -159,17 +159,20 @@ class RDTreePrinter:
|
||||
if child < self.capacity:
|
||||
self.visit.appendleft((child, 0, depth + 1))
|
||||
|
||||
if child == 18446744073709551615:
|
||||
if nprevc != 18446744073709551615:
|
||||
index += '┌'
|
||||
elif nnext != 18446744073709551615:
|
||||
index += '├'
|
||||
else:
|
||||
index += '└'
|
||||
elif nprevc != 18446744073709551615:
|
||||
index += '─'
|
||||
else:
|
||||
index += '└'
|
||||
if child == 18446744073709551615: # If the child is NULL
|
||||
if nprevc != 18446744073709551615: # And there was a previous child
|
||||
if nnext != 18446744073709551615: # And there is a next node
|
||||
index += '┌' # Begin new branch
|
||||
else: # Otherwise
|
||||
index += '─' # Add single branch
|
||||
elif nnext != 18446744073709551615: # Else if there is a next node
|
||||
index += '├' # Continue Branch
|
||||
else: # Otherwise
|
||||
index += '└' # Terminate Branch
|
||||
elif nprevc != 18446744073709551615: # Else if there is a previous child (this node has a child)
|
||||
index += '─' # Add single branch
|
||||
else: # Otherwise
|
||||
index += '└' # Terminate Branch
|
||||
|
||||
index += '─'
|
||||
index += '[{}]'.format(i)
|
||||
@@ -195,6 +198,104 @@ class RDTreePrinter:
|
||||
return self.Iterator(self.tree, 0, self.capacity)
|
||||
|
||||
|
||||
# SET ==================================================================================================================
|
||||
|
||||
class SetPrinter:
|
||||
|
||||
class Iterator:
|
||||
def __init__(self, table, capacity):
|
||||
self.table = table
|
||||
self.capacity = capacity
|
||||
self.node = 0
|
||||
self.index = 0
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def __next__(self):
|
||||
while self.node < self.capacity:
|
||||
if self.table[self.node]['value']['_set']:
|
||||
break
|
||||
self.node = self.node + 1
|
||||
|
||||
if self.node >= self.capacity:
|
||||
raise StopIteration
|
||||
|
||||
i = self.index
|
||||
value = self.table[self.node]['value']['_val']
|
||||
self.node = self.node + 1
|
||||
self.index = self.index + 1
|
||||
return '[{}]'.format(i), value
|
||||
|
||||
def __init__(self, val):
|
||||
self.table = val['_alloc']['_data']
|
||||
self.capacity = val['_alloc']['_capacity']
|
||||
self.size = val['_size']
|
||||
|
||||
def to_string(self):
|
||||
if self.size == 0:
|
||||
return "{ empty }"
|
||||
return "{ size = " + str(self.size) + " }"
|
||||
|
||||
def children(self):
|
||||
return self.Iterator(self.table, self.capacity)
|
||||
|
||||
|
||||
# MAP ==================================================================================================================
|
||||
|
||||
class MapPrinter:
|
||||
|
||||
class Iterator:
|
||||
def __init__(self, table, capacity):
|
||||
self.table = table
|
||||
self.capacity = capacity
|
||||
self.node = 0
|
||||
self.index = 0
|
||||
self.move = False
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def __next__(self):
|
||||
while self.node < self.capacity:
|
||||
if self.table[self.node]['value']['_set']:
|
||||
break
|
||||
self.node = self.node + 1
|
||||
|
||||
if self.node >= self.capacity:
|
||||
raise StopIteration
|
||||
|
||||
i = self.index
|
||||
pair = self.table[self.node]['value']['_val']
|
||||
key = pair['first']
|
||||
val = pair['second']
|
||||
|
||||
if not self.move:
|
||||
self.move = True
|
||||
return ('key' + str(i), key)
|
||||
else:
|
||||
self.move = False
|
||||
self.index = self.index + 1
|
||||
self.node = self.node + 1
|
||||
return ('value' + str(i), val)
|
||||
|
||||
def __init__(self, val):
|
||||
self.table = val['_set']['_alloc']['_data']
|
||||
self.capacity = val['_set']['_alloc']['_capacity']
|
||||
self.size = val['_set']['_size']
|
||||
|
||||
def to_string(self):
|
||||
if self.size == 0:
|
||||
return "{ empty }"
|
||||
return "{ size = " + str(self.size) + " }"
|
||||
|
||||
def children(self):
|
||||
return self.Iterator(self.table, self.capacity)
|
||||
|
||||
def display_hint(self):
|
||||
return 'map'
|
||||
|
||||
|
||||
# GDB Code =============================================================================================================
|
||||
|
||||
def register_printers():
|
||||
@@ -206,6 +307,8 @@ def register_printers():
|
||||
pp.add_printer('dynarray', '^fennec::dynarray<.*>$', DynArrayPrinter)
|
||||
pp.add_printer('list', '^fennec::list<.*>$', ListPrinter)
|
||||
pp.add_printer('rdtree', '^fennec::rdtree<.*>$', RDTreePrinter)
|
||||
pp.add_printer('set', '^fennec::set<.*>$', SetPrinter)
|
||||
pp.add_printer('map', '^fennec::map<.*>$', MapPrinter)
|
||||
return pp
|
||||
|
||||
printer = register_printers()
|
||||
@@ -25,9 +25,20 @@ class AllocationPrinter:
|
||||
self.val = val
|
||||
|
||||
def to_string(self):
|
||||
return "fennec::allocation = " + str(self.val['_capacity'])
|
||||
return "{ capacity = " + str(self.val['_capacity']) + " }"
|
||||
|
||||
def children(self):
|
||||
size = int(self.val['_capacity'])
|
||||
start = self.val['_data']
|
||||
return (('[{}]'.format(i), start[i]) for i in range(size))
|
||||
|
||||
|
||||
# GDB Code =============================================================================================================
|
||||
|
||||
def register_printers():
|
||||
print("registering memory")
|
||||
pp = gdb.printing.RegexpCollectionPrettyPrinter("fennec::memory")
|
||||
pp.add_printer('allocation', '^fennec::allocation<.*>$', AllocationPrinter)
|
||||
return pp
|
||||
|
||||
printer = register_printers()
|
||||
@@ -24,24 +24,39 @@ class CStringPrinter:
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string(self):
|
||||
return str(self.val['_cstr'])
|
||||
def display_hint(self):
|
||||
return 'string'
|
||||
|
||||
def children(self):
|
||||
size = int(self.val['_size'])
|
||||
start = self.val['_cstr']
|
||||
return (('[{}]'.format(i), start[i]) for i in range(size))
|
||||
def to_string(self):
|
||||
value = "\"" + self.val['_str'].string('', 'replace', self.val['_size'] - 1) + "\""
|
||||
return value
|
||||
|
||||
def display_hint(self):
|
||||
return 'string'
|
||||
|
||||
|
||||
# STRING ===============================================================================================================
|
||||
class StringPrinter:
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
self.val = val['_str']
|
||||
|
||||
def to_string(self):
|
||||
return str(self.val['_str']['_data'])
|
||||
value = "\"" + self.val['_data'].string('', 'replace', self.val['_capacity'] - 1) + "\""
|
||||
return value
|
||||
|
||||
def children(self):
|
||||
size = int(self.val['_str']['_capacity'])
|
||||
start = self.val['_str']['_data']
|
||||
return (('[{}]'.format(i), start[i]) for i in range(size))
|
||||
def display_hint(self):
|
||||
return 'string'
|
||||
|
||||
|
||||
# GDB Code =============================================================================================================
|
||||
|
||||
def register_printers():
|
||||
print("registering strings")
|
||||
pp = gdb.printing.RegexpCollectionPrettyPrinter("fennec::strings")
|
||||
pp.add_printer('cstring', '^fennec::cstring$', CStringPrinter)
|
||||
pp.add_printer('wcstring', '^fennec::wcstring$', CStringPrinter)
|
||||
pp.add_printer('string', '^fennec::_string<.*>$', StringPrinter)
|
||||
pp.add_printer('wstring', '^fennec::_wstring<.*>$', StringPrinter)
|
||||
return pp
|
||||
|
||||
printer = register_printers()
|
||||
@@ -235,7 +235,7 @@ public:
|
||||
int p0 = psl - n, p1 = psl + n;
|
||||
bool c0 = false, c1 = false;
|
||||
|
||||
if ((c0 = (p0 > 0 && _alloc[i0].psl >= p0)) && _alloc[i0].value) {
|
||||
if ((c0 = (p0 >= 0 && _alloc[i0].psl >= p0)) && _alloc[i0].value) {
|
||||
if (*_alloc[i0].value == val) {
|
||||
return iterator(this, i);
|
||||
}
|
||||
|
||||
@@ -92,6 +92,16 @@ public:
|
||||
_str[n] = '\0';
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Buffer Constructor, wraps the provided C-Style string
|
||||
/// \param str the buffer to wrap
|
||||
/// \tparam n the number of characters in the buffer plus the null terminator
|
||||
template<size_t n>
|
||||
constexpr _string(char(&str)[n])
|
||||
: _str(str, n) {
|
||||
assert(_str[n - 1] == '\0', "Invalid NTBS.");
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Buffer Copy Constructor
|
||||
/// \param str the buffer to copy
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
|
||||
int main(int, char **)
|
||||
{
|
||||
srand(0);
|
||||
|
||||
fennec_test_header("fennec-test, a program to execute unit tests for fennec");
|
||||
|
||||
fennec_test_spacer(2);
|
||||
|
||||
@@ -31,10 +31,8 @@ namespace fennec::test
|
||||
const char string[] = "Hello World!";
|
||||
array<char, sizeof(string)> arr1;
|
||||
array<char, sizeof(string)> arr2;
|
||||
std::array<char, sizeof(string)> stdarr;
|
||||
strcpy(&arr1[0], string);
|
||||
strcpy(&arr2[0], string);
|
||||
strcpy(&stdarr[0], string);
|
||||
|
||||
fennec_test_run(strcmp(&arr1[0], string), 0);
|
||||
fennec_test_run(strcmp(&arr2[0], string), 0);
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace fennec::test
|
||||
dynarray<int> test1;
|
||||
dynarray<int> test2;
|
||||
|
||||
int n = 10000;
|
||||
int n = 50;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
test1.push_back(i);
|
||||
test2.push_back(n - i - 1);
|
||||
|
||||
@@ -33,7 +33,7 @@ inline void fennec_test_containers_list() {
|
||||
|
||||
list<size_t> test;
|
||||
|
||||
const size_t n = 10000;
|
||||
const size_t n = 50;
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
const size_t p = rand() % (i + 1);
|
||||
assertf(test.insert(p, i) == i, "List Construct Test Failed.");
|
||||
|
||||
@@ -33,7 +33,7 @@ inline void fennec_test_containers_rdtree() {
|
||||
|
||||
rdtree<size_t> test;
|
||||
|
||||
const size_t n = 10000;
|
||||
const size_t n = 50;
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
const size_t parent = rand() % (i + 1);
|
||||
const size_t child = rdtree<size_t>::npos;
|
||||
|
||||
@@ -31,18 +31,19 @@ namespace fennec::test
|
||||
inline void fennec_test_containers_set() {
|
||||
|
||||
using type_t = decltype(rand());
|
||||
std::unordered_set<type_t> ref;
|
||||
list<type_t> ref;
|
||||
set<type_t> test;
|
||||
|
||||
srand(0);
|
||||
for (int i = 0; i < 10000; ++i) {
|
||||
int n = 50;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
type_t v = rand();
|
||||
ref.insert(v);
|
||||
test.insert(v);
|
||||
ref.push_back(v);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10000; ++i) {
|
||||
assertf(ref.contains(i) == test.contains(i), "set test failed");
|
||||
for (int i = 0; i < n; ++i) {
|
||||
type_t v = ref[i];
|
||||
assertf(test.contains(v), "set test failed");
|
||||
}
|
||||
|
||||
std::cout << "passed" << std::endl;
|
||||
|
||||
Reference in New Issue
Block a user