- 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
|
python
|
||||||
import sys, os.path
|
import sys, os.path
|
||||||
print(os.path.abspath("./gdbpp"))
|
print(os.path.abspath("./gdb"))
|
||||||
sys.path.insert(0, os.path.abspath("./gdbpp"))
|
sys.path.insert(0, os.path.abspath("./gdb"))
|
||||||
import fennec
|
import fennec
|
||||||
fennec.register_printers(gdb.current_objfile())
|
fennec.register_printers(gdb.current_objfile())
|
||||||
end
|
end
|
||||||
@@ -20,7 +20,12 @@
|
|||||||
# GDB CODE =============================================================================================================
|
# GDB CODE =============================================================================================================
|
||||||
|
|
||||||
import gdb
|
import gdb
|
||||||
from .containers import *
|
|
||||||
|
from . import containers
|
||||||
|
from . import strings
|
||||||
|
from . import memory
|
||||||
|
|
||||||
def register_printers(obj):
|
def register_printers(obj):
|
||||||
gdb.printing.register_pretty_printer(obj, containers.printer)
|
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:
|
class RDTreePrinter:
|
||||||
"""Print a fennec::rdtree"""
|
"""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):
|
def __init__(self, tree, node, capacity):
|
||||||
self.tree = tree
|
self.tree = tree
|
||||||
self.capacity = capacity
|
self.capacity = capacity
|
||||||
@@ -151,7 +151,7 @@ class RDTreePrinter:
|
|||||||
nprevc = self.tree[nprev]['child'] if nprev != 18446744073709551615 else 18446744073709551615
|
nprevc = self.tree[nprev]['child'] if nprev != 18446744073709551615 else 18446744073709551615
|
||||||
child = self.tree[node]['child']
|
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:
|
if nnext < self.capacity:
|
||||||
self.visit.appendleft((nnext, i + 1, depth))
|
self.visit.appendleft((nnext, i + 1, depth))
|
||||||
@@ -159,17 +159,20 @@ class RDTreePrinter:
|
|||||||
if child < self.capacity:
|
if child < self.capacity:
|
||||||
self.visit.appendleft((child, 0, depth + 1))
|
self.visit.appendleft((child, 0, depth + 1))
|
||||||
|
|
||||||
if child == 18446744073709551615:
|
if child == 18446744073709551615: # If the child is NULL
|
||||||
if nprevc != 18446744073709551615:
|
if nprevc != 18446744073709551615: # And there was a previous child
|
||||||
index += '┌'
|
if nnext != 18446744073709551615: # And there is a next node
|
||||||
elif nnext != 18446744073709551615:
|
index += '┌' # Begin new branch
|
||||||
index += '├'
|
else: # Otherwise
|
||||||
else:
|
index += '─' # Add single branch
|
||||||
index += '└'
|
elif nnext != 18446744073709551615: # Else if there is a next node
|
||||||
elif nprevc != 18446744073709551615:
|
index += '├' # Continue Branch
|
||||||
index += '─'
|
else: # Otherwise
|
||||||
else:
|
index += '└' # Terminate Branch
|
||||||
index += '└'
|
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 += '─'
|
||||||
index += '[{}]'.format(i)
|
index += '[{}]'.format(i)
|
||||||
@@ -195,6 +198,104 @@ class RDTreePrinter:
|
|||||||
return self.Iterator(self.tree, 0, self.capacity)
|
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 =============================================================================================================
|
# GDB Code =============================================================================================================
|
||||||
|
|
||||||
def register_printers():
|
def register_printers():
|
||||||
@@ -206,6 +307,8 @@ def register_printers():
|
|||||||
pp.add_printer('dynarray', '^fennec::dynarray<.*>$', DynArrayPrinter)
|
pp.add_printer('dynarray', '^fennec::dynarray<.*>$', DynArrayPrinter)
|
||||||
pp.add_printer('list', '^fennec::list<.*>$', ListPrinter)
|
pp.add_printer('list', '^fennec::list<.*>$', ListPrinter)
|
||||||
pp.add_printer('rdtree', '^fennec::rdtree<.*>$', RDTreePrinter)
|
pp.add_printer('rdtree', '^fennec::rdtree<.*>$', RDTreePrinter)
|
||||||
|
pp.add_printer('set', '^fennec::set<.*>$', SetPrinter)
|
||||||
|
pp.add_printer('map', '^fennec::map<.*>$', MapPrinter)
|
||||||
return pp
|
return pp
|
||||||
|
|
||||||
printer = register_printers()
|
printer = register_printers()
|
||||||
@@ -25,9 +25,20 @@ class AllocationPrinter:
|
|||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
def to_string(self):
|
def to_string(self):
|
||||||
return "fennec::allocation = " + str(self.val['_capacity'])
|
return "{ capacity = " + str(self.val['_capacity']) + " }"
|
||||||
|
|
||||||
def children(self):
|
def children(self):
|
||||||
size = int(self.val['_capacity'])
|
size = int(self.val['_capacity'])
|
||||||
start = self.val['_data']
|
start = self.val['_data']
|
||||||
return (('[{}]'.format(i), start[i]) for i in range(size))
|
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):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
def to_string(self):
|
def display_hint(self):
|
||||||
return str(self.val['_cstr'])
|
return 'string'
|
||||||
|
|
||||||
def children(self):
|
def to_string(self):
|
||||||
size = int(self.val['_size'])
|
value = "\"" + self.val['_str'].string('', 'replace', self.val['_size'] - 1) + "\""
|
||||||
start = self.val['_cstr']
|
return value
|
||||||
return (('[{}]'.format(i), start[i]) for i in range(size))
|
|
||||||
|
def display_hint(self):
|
||||||
|
return 'string'
|
||||||
|
|
||||||
|
|
||||||
# STRING ===============================================================================================================
|
# STRING ===============================================================================================================
|
||||||
class StringPrinter:
|
class StringPrinter:
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val['_str']
|
||||||
|
|
||||||
def to_string(self):
|
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):
|
def display_hint(self):
|
||||||
size = int(self.val['_str']['_capacity'])
|
return 'string'
|
||||||
start = self.val['_str']['_data']
|
|
||||||
return (('[{}]'.format(i), start[i]) for i in range(size))
|
|
||||||
|
# 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;
|
int p0 = psl - n, p1 = psl + n;
|
||||||
bool c0 = false, c1 = false;
|
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) {
|
if (*_alloc[i0].value == val) {
|
||||||
return iterator(this, i);
|
return iterator(this, i);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,6 +92,16 @@ public:
|
|||||||
_str[n] = '\0';
|
_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
|
/// \brief Buffer Copy Constructor
|
||||||
/// \param str the buffer to copy
|
/// \param str the buffer to copy
|
||||||
|
|||||||
@@ -30,6 +30,8 @@
|
|||||||
|
|
||||||
int main(int, char **)
|
int main(int, char **)
|
||||||
{
|
{
|
||||||
|
srand(0);
|
||||||
|
|
||||||
fennec_test_header("fennec-test, a program to execute unit tests for fennec");
|
fennec_test_header("fennec-test, a program to execute unit tests for fennec");
|
||||||
|
|
||||||
fennec_test_spacer(2);
|
fennec_test_spacer(2);
|
||||||
|
|||||||
@@ -31,10 +31,8 @@ namespace fennec::test
|
|||||||
const char string[] = "Hello World!";
|
const char string[] = "Hello World!";
|
||||||
array<char, sizeof(string)> arr1;
|
array<char, sizeof(string)> arr1;
|
||||||
array<char, sizeof(string)> arr2;
|
array<char, sizeof(string)> arr2;
|
||||||
std::array<char, sizeof(string)> stdarr;
|
|
||||||
strcpy(&arr1[0], string);
|
strcpy(&arr1[0], string);
|
||||||
strcpy(&arr2[0], string);
|
strcpy(&arr2[0], string);
|
||||||
strcpy(&stdarr[0], string);
|
|
||||||
|
|
||||||
fennec_test_run(strcmp(&arr1[0], string), 0);
|
fennec_test_run(strcmp(&arr1[0], string), 0);
|
||||||
fennec_test_run(strcmp(&arr2[0], string), 0);
|
fennec_test_run(strcmp(&arr2[0], string), 0);
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ namespace fennec::test
|
|||||||
dynarray<int> test1;
|
dynarray<int> test1;
|
||||||
dynarray<int> test2;
|
dynarray<int> test2;
|
||||||
|
|
||||||
int n = 10000;
|
int n = 50;
|
||||||
for (int i = 0; i < n; ++i) {
|
for (int i = 0; i < n; ++i) {
|
||||||
test1.push_back(i);
|
test1.push_back(i);
|
||||||
test2.push_back(n - i - 1);
|
test2.push_back(n - i - 1);
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ inline void fennec_test_containers_list() {
|
|||||||
|
|
||||||
list<size_t> test;
|
list<size_t> test;
|
||||||
|
|
||||||
const size_t n = 10000;
|
const size_t n = 50;
|
||||||
for (size_t i = 0; i < n; ++i) {
|
for (size_t i = 0; i < n; ++i) {
|
||||||
const size_t p = rand() % (i + 1);
|
const size_t p = rand() % (i + 1);
|
||||||
assertf(test.insert(p, i) == i, "List Construct Test Failed.");
|
assertf(test.insert(p, i) == i, "List Construct Test Failed.");
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ inline void fennec_test_containers_rdtree() {
|
|||||||
|
|
||||||
rdtree<size_t> test;
|
rdtree<size_t> test;
|
||||||
|
|
||||||
const size_t n = 10000;
|
const size_t n = 50;
|
||||||
for (size_t i = 0; i < n; ++i) {
|
for (size_t i = 0; i < n; ++i) {
|
||||||
const size_t parent = rand() % (i + 1);
|
const size_t parent = rand() % (i + 1);
|
||||||
const size_t child = rdtree<size_t>::npos;
|
const size_t child = rdtree<size_t>::npos;
|
||||||
|
|||||||
@@ -31,18 +31,19 @@ namespace fennec::test
|
|||||||
inline void fennec_test_containers_set() {
|
inline void fennec_test_containers_set() {
|
||||||
|
|
||||||
using type_t = decltype(rand());
|
using type_t = decltype(rand());
|
||||||
std::unordered_set<type_t> ref;
|
list<type_t> ref;
|
||||||
set<type_t> test;
|
set<type_t> test;
|
||||||
|
|
||||||
srand(0);
|
int n = 50;
|
||||||
for (int i = 0; i < 10000; ++i) {
|
for (int i = 0; i < n; ++i) {
|
||||||
type_t v = rand();
|
type_t v = rand();
|
||||||
ref.insert(v);
|
|
||||||
test.insert(v);
|
test.insert(v);
|
||||||
|
ref.push_back(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 10000; ++i) {
|
for (int i = 0; i < n; ++i) {
|
||||||
assertf(ref.contains(i) == test.contains(i), "set test failed");
|
type_t v = ref[i];
|
||||||
|
assertf(test.contains(v), "set test failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "passed" << std::endl;
|
std::cout << "passed" << std::endl;
|
||||||
|
|||||||
Reference in New Issue
Block a user