From: Chris Koeritz Date: Sun, 3 Oct 2021 20:55:24 +0000 (-0400) Subject: Merge branch 'release-2.140.128' into main X-Git-Tag: 2.140.128^0 X-Git-Url: https://feistymeow.org/gitweb/?p=feisty_meow.git;a=commitdiff_plain;h=e4a4fe4d563678d4348bb49cb17cd967206c248c;hp=2caf2cc35c2fbbcd1865fd3e24342886c28cd5a7 Merge branch 'release-2.140.128' into main --- diff --git a/infobase/examples/web/simple-index.html b/infobase/examples/web/simple-index.html new file mode 100644 index 00000000..5d149d1b --- /dev/null +++ b/infobase/examples/web/simple-index.html @@ -0,0 +1,13 @@ + + + + Title goes right here! + + +

+Here's an example paragraph in this amazing web site, which demonstrates a super simple basic html file. +Anything in the body tag will appear on the page, just like this p tag and its contents. +

+ + + diff --git a/nucleus/library/nodes/symbol_tree.cpp b/nucleus/library/nodes/symbol_tree.cpp index bd985a27..ba5c33f9 100644 --- a/nucleus/library/nodes/symbol_tree.cpp +++ b/nucleus/library/nodes/symbol_tree.cpp @@ -24,7 +24,7 @@ #include #undef LOG -#define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), s) +#define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), astring(s) + a_sprintf(" [obj=%p]", this)) using namespace loggers; using namespace basis; @@ -40,7 +40,7 @@ public: symbol_tree_associations(int estimated_elements) : symbol_table(estimated_elements) {} virtual ~symbol_tree_associations() { -//hmmm: why was this here? was it ever needed? +//probably we don't actually want to whack here??? // for (int i = 0; i < symbols(); i++) { // WHACK(use(i)); // } @@ -54,15 +54,23 @@ symbol_tree::symbol_tree(const astring &node_name, int estimated_elements) _associations(new symbol_tree_associations(estimated_elements)), _name(new astring(node_name)) { + FUNCDEF("constructor") } symbol_tree::~symbol_tree() { FUNCDEF("destructor"); -LOG("prior to whacks"); +#ifdef DEBUG_SYMBOL_TREE + LOG("symtree dtor: prior to whacks"); +#endif WHACK(_associations); +#ifdef DEBUG_SYMBOL_TREE + LOG("symtree dtor: after whacking associations"); +#endif WHACK(_name); -LOG("after whacks"); +#ifdef DEBUG_SYMBOL_TREE + LOG("symtree dtor: after all whacks"); +#endif } int symbol_tree::children() const { return _associations->symbols(); } @@ -93,26 +101,33 @@ outcome symbol_tree::prune(tree *to_zap_in) FUNCDEF("prune"); #endif symbol_tree *to_zap = dynamic_cast(to_zap_in); - if (!to_zap) { + if (to_zap) { #ifdef DEBUG_SYMBOL_TREE - LOG("about to barf due to null symtree after dynamic cast."); + LOG(astring("zapping node for ") + to_zap->name()); #endif - throw("error: symbol_tree::prune: wrong type of node in prune"); - } + int found = which(to_zap); // find the node in the tree. + if (negative(found)) return common::NOT_FOUND; // not found. +#ifdef DEBUG_SYMBOL_TREE + int kids = _associations->symbols(); +#endif + _associations->whack(to_zap->name()); // remove from associations. #ifdef DEBUG_SYMBOL_TREE - LOG(astring("zapping node for ") + to_zap->name()); + if (kids - 1 != _associations->symbols()) + throw("error: symbol_tree::prune: failed to crop kid in symtab"); #endif - int found = which(to_zap); // find the node in the tree. - if (negative(found)) return common::NOT_FOUND; // not found. + } else { #ifdef DEBUG_SYMBOL_TREE - int kids = _associations->symbols(); + LOG("skip symtree prune steps due to null symtree after dynamic cast."); #endif - _associations->whack(to_zap->name()); // remove from associations. +///hmmm: how about not? throw("error: symbol_tree::prune: wrong type of node in prune"); + } #ifdef DEBUG_SYMBOL_TREE - if (kids - 1 != _associations->symbols()) - throw("error: symbol_tree::prune: failed to crop kid in symtab"); + LOG("about to call base tree::prune..."); #endif tree::prune(to_zap); // remove from tree. +#ifdef DEBUG_SYMBOL_TREE + LOG("after called base tree::prune."); +#endif return common::OKAY; } diff --git a/nucleus/library/nodes/tree.cpp b/nucleus/library/nodes/tree.cpp index 7398274b..2a1300da 100644 --- a/nucleus/library/nodes/tree.cpp +++ b/nucleus/library/nodes/tree.cpp @@ -18,15 +18,17 @@ #include #include #include +#include //#define DEBUG_TREE // uncomment if you want lots of debugging info. #undef LOG -#define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), s) +#define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), astring(s) + a_sprintf(" [obj=%p]", this)) using namespace basis; using namespace loggers; +using namespace structures; namespace nodes { @@ -277,14 +279,19 @@ tree::tree() tree::~tree() { FUNCDEF("destructor"); - // must at least unhook ourselves from the parent so we don't become a lost - // cousin. - tree *my_parent = parent(); - if (my_parent) my_parent->prune(this); - my_parent = NULL_POINTER; // disavow since we are loose now. +#ifdef DEBUG_TREE + LOG("entry to tree destructor"); +#endif + { + // must at least unhook ourselves from the parent so we don't become a lost + // cousin. + tree *my_parent = parent(); + if (my_parent) my_parent->prune(this); + } #if 0 //hmmm: clean this code when it's been examined long enough. maybe already. +LOG("old code for tree destructor activating..."); //original version suffers from being too recursive on windoze, //which blows out the stack. linux never showed this problem. so, i @@ -297,41 +304,125 @@ tree::~tree() // iterate over the child nodes and whack each individually. while (branches()) delete branch(0); // this relies on the child getting out of our branch list. -#else +#endif + +#if 0 + LOG("new code for tree destructor activating..."); + +//hmmm: this new code stinks on ice. keeps doing something awful, either double deleting or deleting wrong thing. +// why didn't we just use our own iterator to traverse the tree depth first and clean that way?? // newer version of delete doesn't recurse; it just iterates instead, // which avoids the massive recursive depth of the original approach. - tree *curr_node = this; - tree *stop_node = this; // don't whack self. - while (curr_node != NULL_POINTER) { - // make a breadcrumb for getting back to 'here' in the tree. - tree *way_back = curr_node; - // our main operation here is to go down a node without using any - // stack frames. so we just pick the first kid; it's either valid - // or there are no kids at all. - curr_node = curr_node->branch(0); - - if (curr_node == NULL_POINTER) { - // wayback has no children, so we can take action. - - // if wayback is the same as "this", then we exit from iterations since - // we've cleaned all the kids out. - if (way_back == this) { - break; - } + while (branches()) { + // we know we have a branch to work on, due to conditional above. + tree *stop_node = branch(0); // don't whack the node we're at until we're done with its kids. + tree *curr_node = stop_node; + while (curr_node != NULL_POINTER) { + // make a breadcrumb for getting back to 'here' in the tree. + tree *way_back = curr_node; + // our main operation here is to go down a node without using any + // stack frames. so we just pick the first kid; it's either valid + // or there are no kids at all. + curr_node = curr_node->branch(0); + + if (curr_node == NULL_POINTER) { + // wayback has no children, so we can take action. +LOG("tree dtor: can take action on childless node..."); + + // if wayback is the same as stop_node, then we exit from iterations since + // we've cleaned all the kids out. + if (way_back == stop_node) { +LOG("tree dtor: stopping since at wayback node..."); + // we can actually delete wayback here, because we are at the stopping point. + // and since a tree node whack removes it from its parent, we are clean one branch now. + WHACK(way_back); +LOG("tree dtor: whacked wayback before inner break."); + break; + } - // we want to whack the wayback node at this point, since it's a parent - // with no kids, i.e. a leaf. we've guaranteed we're not going beyond - // our remit, since wayback is not the same node as the top level one - // in the destructor (as long as there are no cycles in the tree...). - curr_node = way_back->parent(); // go up in tree on next iteration. - WHACK(way_back); // whack a node, finally. - } else { - // okay, there's a node below here. we will spider down to it. - continue; + // we want to whack the wayback node at this point, since it's a parent + // with no kids, i.e. a leaf. we've guaranteed we're not going beyond + // our remit, since wayback is not the same node as the top level one + // in the destructor (as long as there are no cycles in the tree...). + curr_node = way_back->parent(); // go up in tree on next iteration. + +LOG("tree dtor: reset currnode, about to whack wayback..."); + + if (curr_node == stop_node) { +LOG("tree dtor: seeing curr_node hits our stop_node!"); +/// break; + } else if (curr_node == stop_node->parent()) { +LOG("tree dtor: seeing curr_node ABOVE our stop_node!"); + } + + WHACK(way_back); // whack a node, finally. + +LOG("tree dtor: after whacking wayback..."); + } else { + // okay, there's a node below here. we will spider down to it. +LOG("tree dtor: spidering to node below..."); + continue; + } } } +#endif + +#if 1 +#ifdef DEBUG_TREE + LOG("newest code for tree destructor (stack based) activating..."); +#endif + + // this version of delete doesn't recurse; it just iterates instead, + // which avoids the massive recursive depth of the original approach. + // it does use a stack object however, but that will use main memory, + // which is usually in greater supply than stack/heap space. + + stack sleestak; // accumulates nodes that we still need to clean up. + + // iterate across this node first, to feed the stack. + // we feed it in reverse branch order, so that the first branch will be dealt with first (popped off stack first). + while (branches()) { + // get our current last branch... + tree *bran = branch(branches() - 1); + // pull that branch off the tree (non-destructively)... + prune(bran); + // and add that branch to the stack. +#ifdef DEBUG_TREE + LOG(a_sprintf("tree dtor: adding child %p on stack.", bran)); +#endif + sleestak.push(bran); + } + + // now iterate across our stack until we have dealt with every node in it. + while (sleestak.size()) { + + tree *popper = NULL_POINTER; + sleestak.acquire_pop(popper); +#ifdef DEBUG_TREE + LOG(a_sprintf("tree dtor: popped a tree %p off stack.", popper)); +#endif + + // familiar scheme below; push last branch first, then we'll pop first branch first. + while (popper->branches()) { + tree *bran = popper->branch(popper->branches() - 1); + popper->prune(bran); +#ifdef DEBUG_TREE + LOG(a_sprintf("tree dtor: inner, adding child %p on stack.", bran)); +#endif + sleestak.push(bran); + } + // now the popper gets cleaned up; this should be totally safe since all its kids + // have been pruned and put into the stack. +#ifdef DEBUG_TREE + LOG(a_sprintf("tree dtor: about to zap a tree %p.", popper)); +#endif + WHACK(popper); +#ifdef DEBUG_TREE + LOG("tree dtor: whacked that tree."); +#endif + } #endif } @@ -387,11 +478,24 @@ outcome tree::prune(tree *branch_to_cut) outcome tree::prune_index(int branch_to_cut) { + FUNCDEF("prune_index"); branch_to_cut++; bounds_return(branch_to_cut, 1, branches(), basis::common::NOT_FOUND); +#ifdef DEBUG_TREE + LOG(a_sprintf("got legit branch %d to cut", branch_to_cut)); +#endif tree *that_branch = (tree *)get_link(branch_to_cut); +#ifdef DEBUG_TREE + LOG(a_sprintf("whacking off branch %p", that_branch)); +#endif that_branch->set_link(BACKWARDS_BRANCH, NULL_POINTER); +#ifdef DEBUG_TREE + LOG(a_sprintf("zapping link branch %d", branch_to_cut)); +#endif zap_link(branch_to_cut); +#ifdef DEBUG_TREE + LOG("returning, finished."); +#endif return basis::common::OKAY; } diff --git a/nucleus/library/tests_nodes/test_node.cpp b/nucleus/library/tests_nodes/test_node.cpp index 82dfb77c..e76a8439 100644 --- a/nucleus/library/tests_nodes/test_node.cpp +++ b/nucleus/library/tests_nodes/test_node.cpp @@ -80,6 +80,8 @@ int test_node::execute() george.set_link(0, &g_end1); george.set_link(1, &g_end2); +//do some testing on those results!!! + return final_report(); } diff --git a/nucleus/library/tests_nodes/test_symbol_tree.cpp b/nucleus/library/tests_nodes/test_symbol_tree.cpp index fa4a5c8c..64e917e0 100644 --- a/nucleus/library/tests_nodes/test_symbol_tree.cpp +++ b/nucleus/library/tests_nodes/test_symbol_tree.cpp @@ -41,7 +41,7 @@ using namespace unit_test; #define LOG(to_print) EMERGENCY_LOG(program_wide_logger().get(), astring(to_print)) -#define DEBUG_SYMBOL_TREE +//#define DEBUG_TEST_SYMBOL_TREE // how many nodes we add to the tree. const int MAX_NODES_TESTED = 40000; @@ -73,15 +73,26 @@ int test_symbol_tree::execute() astring rando = string_manipulation::make_random_name(1, 10); curr->add(new symbol_tree(rando)); } -LOG("about to whack dynamic tree..."); +#ifdef DEBUG_TEST_SYMBOL_TREE + LOG("about to whack dynamic tree..."); +#endif WHACK(t); -LOG("dynamic tree whacked."); + ASSERT_EQUAL(t, NULL_POINTER, "ensure pointer cleaned up"); +#ifdef DEBUG_TEST_SYMBOL_TREE + LOG("dynamic tree whacked."); +#endif } catch (...) { +#ifdef DEBUG_TEST_SYMBOL_TREE LOG("crashed during tree stuffing."); +#endif return 1; } -//hmmm: create a more balanced tree structure... + ASSERT_TRUE(true, "testing succeeded without cleanup crashes"); + + + +//hmmm: need more tests, like where we create a more balanced tree structure... // perform known operations and validate shape of tree. return final_report(); diff --git a/nucleus/library/tests_nodes/test_tree.cpp b/nucleus/library/tests_nodes/test_tree.cpp index 1b60c496..d0b0a434 100644 --- a/nucleus/library/tests_nodes/test_tree.cpp +++ b/nucleus/library/tests_nodes/test_tree.cpp @@ -1,15 +1,14 @@ /* -* Name : test_tree * -* Author : Chris Koeritz * -* Purpose: * -* Tests out the tree class. * +* Name : test_tree +* Author : Chris Koeritz +* Purpose: Tests out the tree class. ** -* Copyright (c) 1993-$now By Author. This program is free software; you can * -* redistribute it and/or modify it under the terms of the GNU General Public * -* License as published by the Free Software Foundation; either version 2 of * -* the License or (at your option) any later version. This is online at: * -* http://www.fsf.org/copyleft/gpl.html * -* Please send any updates to: fred@gruntose.com * +* Copyright (c) 1993-$now By Author. This program is free software; you can +* redistribute it and/or modify it under the terms of the GNU General Public +* License as published by the Free Software Foundation; either version 2 of +* the License or (at your option) any later version. This is online at: +* http://www.fsf.org/copyleft/gpl.html +* Please send any updates to: fred@gruntose.com */ #include diff --git a/scripts/agenda/info_overload_report.sh b/scripts/agenda/info_overload_report.sh index 1812d87e..dcb5f171 100644 --- a/scripts/agenda/info_overload_report.sh +++ b/scripts/agenda/info_overload_report.sh @@ -140,6 +140,9 @@ analyze_hierarchy_and_report $CLOUD_BASE/disordered "disordered and maybe derang # up our weight accounting considerably. analyze_hierarchy_and_report $CLOUD_BASE/reading "reading list (for a quiet afternoon)" +# bluesky is our brainstorming and wunderthinking area for new things. +analyze_hierarchy_and_report $CLOUD_BASE/blue_sky "blue sky is the limit ideas" + #### # vocation is a prefix for anything i consider part of my life's work. diff --git a/scripts/marks/create_marks.sh b/scripts/marks/create_marks.sh index 40b07b4e..b8b79ea4 100644 --- a/scripts/marks/create_marks.sh +++ b/scripts/marks/create_marks.sh @@ -46,5 +46,4 @@ if [ $? != 0 ]; then fi \mv -f $genlinx $genlinx_moz $genlinx_js $GRUNTOSE_DIR/Info/Twain -\mv -f $newmarx $HOME