Merge branch 'release-2.140.128' into main 2.140.128
authorChris Koeritz <fred@gruntose.com>
Sun, 3 Oct 2021 20:55:24 +0000 (16:55 -0400)
committerChris Koeritz <fred@gruntose.com>
Sun, 3 Oct 2021 20:55:24 +0000 (16:55 -0400)
infobase/examples/web/simple-index.html [new file with mode: 0644]
nucleus/library/nodes/symbol_tree.cpp
nucleus/library/nodes/tree.cpp
nucleus/library/tests_nodes/test_node.cpp
nucleus/library/tests_nodes/test_symbol_tree.cpp
nucleus/library/tests_nodes/test_tree.cpp
scripts/agenda/info_overload_report.sh
scripts/marks/create_marks.sh

diff --git a/infobase/examples/web/simple-index.html b/infobase/examples/web/simple-index.html
new file mode 100644 (file)
index 0000000..5d149d1
--- /dev/null
@@ -0,0 +1,13 @@
+<!doctype html>
+<html>
+  <head>
+    <title>Title goes right here!</title>
+  </head>
+  <body>
+    <p>
+Here's an example paragraph in this amazing web site, which demonstrates a super simple basic html file.
+Anything in the <strong>body</strong> tag will appear on the page, just like this <strong>p</strong> tag and its contents.
+    </p>
+  </body>
+</html>
+
index bd985a27a1c883f6790849ff8b2ab9c65b5c5a2b..ba5c33f948b8a4c15bedeb13c342b9986e4aad5f 100644 (file)
@@ -24,7 +24,7 @@
 
 #include <loggers/program_wide_logger.h>
 #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<symbol_tree *>(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<symbol_tree *>(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;
 }
 
index 7398274bd6e101f324c88e146dad9d32bf095860..2a1300dab06d1e65eb1512a1c43cfa1aa4faab07 100644 (file)
 #include <basis/functions.h>
 #include <basis/guards.h>
 #include <loggers/program_wide_logger.h>
+#include <structures/stack.h>
 
 //#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<tree *> 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;
 }
 
index 82dfb77c67fdefbaeb39dfc1729fdf563d98e514..e76a8439d90483ecbcb9e7cb2c9fbf7c5746397d 100644 (file)
@@ -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();
 }
 
index fa4a5c8cb40c198b7db12eb60b45a14a365629d8..64e917e04c538861207e1bac908a670dce240ec8 100644 (file)
@@ -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();
index 1b60c4961f661f45a68109d94952ea13b13c8455..d0b0a4343f4e290665d104a02b99f3b98102137c 100644 (file)
@@ -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 <application/hoople_main.h>
index 1812d87e7cafed0deda6c319922b6a71980e67b2..dcb5f17101dfbb6d50d75370634fd01493aa1461 100644 (file)
@@ -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.
index 40b07b4ec997d4bfe72376622064a7e6adc170b3..b8b79ea4f46795cbfb44ca043f7eb461d1dd5a1b 100644 (file)
@@ -46,5 +46,4 @@ if [ $? != 0 ]; then
 fi
 
 \mv -f $genlinx $genlinx_moz $genlinx_js $GRUNTOSE_DIR/Info/Twain
-\mv -f $newmarx $HOME