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