implemented new working destructor for tree
[feisty_meow.git] / nucleus / library / tests_nodes / test_tree.cpp
1 /*
2 *  Name   : test_tree
3 *  Author : Chris Koeritz
4 *  Purpose: Tests out the tree class.
5 **
6 * Copyright (c) 1993-$now By Author.  This program is free software; you can
7 * redistribute it and/or modify it under the terms of the GNU General Public
8 * License as published by the Free Software Foundation; either version 2 of
9 * the License or (at your option) any later version.  This is online at:
10 *     http://www.fsf.org/copyleft/gpl.html
11 * Please send any updates to: fred@gruntose.com
12 */
13
14 #include <application/hoople_main.h>
15 #include <basis/astring.h>
16 #include <basis/functions.h>
17 #include <basis/guards.h>
18 #include <loggers/console_logger.h>
19 #include <nodes/node.h>
20 #include <nodes/tree.h>
21 #include <structures/static_memory_gremlin.h>
22 #include <unit_test/unit_base.h>
23
24 using namespace application;
25 using namespace basis;
26 using namespace nodes;
27 using namespace loggers;
28 using namespace structures;
29 using namespace unit_test;
30
31 //#define DEBUG_TEST_TREE
32   // uncomment if you want the noisy streams version.
33
34 const int test_iterations = 20;
35
36 class bogotre : public packable, public tree
37 {
38 public:
39   bogotre(const char *start = NULL_POINTER) : who_cares(42), i_sure_dont('l'),
40         another_useless_int(23) {
41     astring to_init(start);
42     if (to_init.length() < 1) to_init += "ack";
43     to_init.stuff(the_actual_string, minimum(to_init.length()+1, 500));
44   }
45   DEFINE_CLASS_NAME("bogotre");
46   virtual ~bogotre() {}
47   virtual void pack(byte_array &packed_form) const;
48   virtual bool unpack(byte_array &to_unpack);
49   virtual int packed_size() const;
50   virtual abyte *held() const { return (abyte *)the_actual_string; }
51   virtual void print() const {
52 #ifdef DEBUG_TEST_TREE
53     printf(the_actual_string); 
54 #endif
55   }
56
57 private:
58   char the_actual_string[500];
59   int who_cares;
60   char i_sure_dont;
61   int another_useless_int;
62 };
63
64 //////////////
65
66 // forward.
67 typedef bogotre larch;
68 typedef void (applier)(larch *apply_to);
69 typedef tree::iterator traveller;
70
71 class test_tree : public virtual unit_base, virtual public application_shell
72 {
73 public:
74   test_tree() : application_shell() {}
75   DEFINE_CLASS_NAME("test_tree");
76   virtual int execute();
77   static void print_node(larch *curr_node);
78   static larch *next(larch *&move, larch *hook, traveller &skip);
79   static void apply(larch *apply_to, applier *to_apply,
80           tree::traversal_directions order);
81 };
82
83 //////////////
84
85 #undef UNIT_BASE_THIS_OBJECT
86 #define UNIT_BASE_THIS_OBJECT (*dynamic_cast<unit_base *>(application_shell::single_instance()))
87
88 int bogotre::packed_size() const
89 { return strlen(the_actual_string) + 1 + sizeof(int) * 2 + sizeof(abyte); }
90
91 void bogotre::pack(byte_array &packed_form) const
92 {
93   FUNCDEF("pack");
94   astring(the_actual_string).pack(packed_form);
95   structures::attach(packed_form, who_cares);
96   structures::attach(packed_form, i_sure_dont);
97   structures::attach(packed_form, another_useless_int);
98 }
99
100 bool bogotre::unpack(byte_array &packed_form)
101 {
102   FUNCDEF("unpack");
103   // 5 is the magic knowledge of minimum packed string.
104 //hmmm: make the minimum packed size a property of packables?
105   ASSERT_FALSE(packed_form.length() <
106       int(1 + sizeof(who_cares) + sizeof(i_sure_dont) + sizeof(another_useless_int)),
107       "size of package should be correct");
108   astring unpacked;
109   ASSERT_TRUE(unpacked.unpack(packed_form), "should be able to retrieve string");
110   ASSERT_TRUE(structures::detach(packed_form, who_cares), "should retrieve who_cares");
111   ASSERT_TRUE(structures::detach(packed_form, i_sure_dont), "should retrieve i_sure_dont");
112   ASSERT_TRUE(structures::detach(packed_form, another_useless_int),
113       "should retrieve another_...");
114
115   ASSERT_EQUAL(who_cares, 42, "bogotre_unpack - right value held in first int");
116   ASSERT_EQUAL(i_sure_dont, 'l', "bogotre_unpack - right character held");
117   ASSERT_EQUAL(another_useless_int, 23, "bogotre_unpack - right value held in second int");
118   return true;
119 }
120
121 //////////////
122
123 /*
124 bogotre *togen(char *to_store)
125 { bogotre *to_return = new bogotre(astring(to_store).s()); return to_return; }
126 */
127
128 void test_tree::print_node(larch *curr_node)
129 {
130   FUNCDEF("print_node");
131   ASSERT_TRUE(curr_node, "tree shouldn't be nil");
132   bogotre *real_curr = dynamic_cast<bogotre *>(curr_node);
133   ASSERT_TRUE(real_curr, "contents shouldn't be nil");
134   astring to_examine((char *)real_curr->held());
135 #ifdef DEBUG_TEST_TREE
136   to_examine += " ";
137   printf(to_examine.s());
138 //remove it again if we reenable the cut.
139 #endif
140 //  if (to_examine == to_look_for) real_curr->cut();
141 }
142
143 #undef UNIT_BASE_THIS_OBJECT
144 #define UNIT_BASE_THIS_OBJECT (*this)
145
146 //////////////
147
148 larch *test_tree::next(larch *&move, larch *formal(hook), traveller &skip)
149 { move = dynamic_cast<larch *>(skip.next()); return move; }
150
151 void test_tree::apply(larch *apply_to, applier *to_apply,
152     tree::traversal_directions order)
153 {
154   larch *curr = NULL_POINTER;
155   for (traveller skippy = apply_to->start(order);
156        next(curr, apply_to, skippy); ) to_apply(curr);
157 }
158
159 int test_tree::execute()
160 {
161   FUNCDEF("execute");
162   for (int qq = 0; qq < test_iterations; qq++) {
163   larch *e1 = new larch("a");
164   larch *e2 = new larch("b");
165   larch *e3 = new larch("+");
166   e3->attach(e1);
167   e3->attach(e2);
168
169   larch *e4 = new larch("c");
170   larch *e5 = new larch("-");
171   e5->attach(e3);
172   e5->attach(e4);
173
174   larch *e6 = new larch(">");
175   larch *e7 = new larch("23");
176   e6->attach(e5);
177   e6->attach(e7);
178
179   larch *e8 = new larch("d");
180   larch *e9 = new larch("=");
181   e9->attach(e8);
182   e9->attach(e6);
183
184 #ifdef DEBUG_TEST_TREE
185   printf("infix is ");
186 #endif
187   apply(e9, print_node, tree::infix);
188 #ifdef DEBUG_TEST_TREE
189   printf("\nprefix is ");
190 #endif
191   apply(e9, print_node, tree::prefix);
192 #ifdef DEBUG_TEST_TREE
193   printf("\npostfix is ");
194 #endif
195   apply(e9, print_node, tree::postfix);
196 #ifdef DEBUG_TEST_TREE
197   printf("\n");
198   printf("branches is ");
199 #endif
200   apply(e9, print_node, tree::to_branches);
201 #ifdef DEBUG_TEST_TREE
202   printf("\n");
203   printf("branches reversed is ");
204 #endif
205   apply(e9, print_node, tree::reverse_branches);
206 #ifdef DEBUG_TEST_TREE
207   printf("\n");
208   printf("before first pack");
209 #endif
210   byte_array packed_e9(0);
211   int sizzle = e9->packed_size();
212   e9->pack(packed_e9);
213   ASSERT_EQUAL(sizzle, packed_e9.length(), "packed size should agree with results");
214 #ifdef DEBUG_TEST_TREE
215   printf("after first pack, size is %d\n", packed_e9.length());
216 #endif
217   larch *new_e9 = new larch();
218   new_e9->unpack(packed_e9);
219 #ifdef DEBUG_TEST_TREE
220   printf("New tree after unpacking is (infix order):\n");
221 #endif
222   apply(new_e9, print_node, tree::infix);
223 #ifdef DEBUG_TEST_TREE
224   printf("\n");
225 #endif
226 /*
227 #ifdef DEBUG_TEST_TREE
228   printf("the following dumps are in the order: infix, prefix, postfix.\n\n");
229   printf("now trying cut on the character '>':\n");
230 #endif
231   to_look_for = ">";
232   new_e9->apply(&print_node, tree::infix);
233 #ifdef DEBUG_TEST_TREE
234   p("\n");
235 #endif
236   new_e9->apply(&print_node, tree::prefix);
237 #ifdef DEBUG_TEST_TREE
238   p("\n");
239 #endif
240   new_e9->apply(&print_node, tree::postfix);
241 #ifdef DEBUG_TEST_TREE
242   p("\nnow trying cut on the character +:\n");
243 #endif
244   to_look_for = "+";
245   new_e9->apply(&print_node, tree::infix);
246 #ifdef DEBUG_TEST_TREE
247   p("\n");
248 #endif
249   new_e9->apply(&print_node, tree::prefix);
250 #ifdef DEBUG_TEST_TREE
251   p("\n");
252 #endif
253   new_e9->apply(&print_node, tree::postfix);
254 #ifdef DEBUG_TEST_TREE
255   p("\n");
256 #endif
257   to_look_for = "";
258
259 #ifdef DEBUG_TEST_TREE
260   p("okay, trying to resume at -\n");
261 #endif
262   e5->resume(&print_node, tree::infix);
263 #ifdef DEBUG_TEST_TREE
264   p("\n");
265 #endif
266   e5->resume(&print_node, tree::prefix);
267 #ifdef DEBUG_TEST_TREE
268   p("\n");
269 #endif
270   e5->resume(&print_node, tree::postfix);
271 #ifdef DEBUG_TEST_TREE
272   p("\n");
273 #endif
274 */
275 #ifdef DEBUG_TEST_TREE
276   printf("deleting\n");
277 #endif
278   delete e9;
279 /*
280 printf("second pack\n");
281   byte_array second_pack;
282 printf("packing\n");
283   new_e9->pack(second_pack);
284 #ifdef DEBUG_TEST_TREE
285   printf("after second pack, size is %d\n", size);
286 #endif
287 */
288   delete new_e9;
289 /*
290   larch *newest_e9 = new larch(SELF_CLEANING);
291   newest_e9->unpack(second_pack);
292 #ifdef DEBUG_TEST_TREE
293   printf("after second unpack... tree is (infix):\n");
294 #endif
295   newest_e9->apply(print_node, tree::infix);
296   delete newest_e9;
297 #ifdef DEBUG_TEST_TREE
298   p("\n");
299 #endif
300 */
301   }
302   return final_report();
303 }
304
305 HOOPLE_MAIN(test_tree, )
306