1
2 /******************************************************************************
3 * MODULE : observer.cpp
4 * DESCRIPTION: Observers of trees
5 * COPYRIGHT : (C) 1999 Joris van der Hoeven
6 *******************************************************************************
7 * This software falls under the GNU general public license version 3 or later.
8 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
9 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
10 ******************************************************************************/
11
12 #include "modification.hpp"
13 #include "analyze.hpp"
14 #include "hashmap.hpp"
15 #include "blackbox.hpp"
16
17 #define DETACHED (-5)
18
19 observer nil_observer;
20 extern tree the_et;
21 extern bool packrat_invalid_colors;
22
23 /******************************************************************************
24 * Debugging facilities
25 ******************************************************************************/
26
27 static void
consistency_check(tree t,path ip)28 consistency_check (tree t, path ip) {
29 if (obtain_ip (t) != ip)
30 cout << "Wrong ip] " << t << " " << obtain_ip (t)
31 << " instead of " << ip << "\n";
32 if (is_compound (t)) {
33 int i, n= N(t);
34 for (i=0; i<n; i++) {
35 //if (!strong_equal (ip, obtain_ip (t[i])->next))
36 if (obtain_ip (t) != obtain_ip (t[i])->next)
37 cout << "Bad node] " << t << " " << obtain_ip (t) << " #" << i << "\n";
38 consistency_check (t[i], path (i, ip));
39 }
40 }
41 }
42
43 void
consistency_check()44 consistency_check () {
45 consistency_check (the_et, path ());
46 cout << HRULE;
47 }
48
49 void
stretched_print(tree t,bool ips,int indent)50 stretched_print (tree t, bool ips, int indent) {
51 int i;
52 for (i=0; i<indent; i++) cout << " ";
53 if (is_atomic (t)) {
54 cout << raw_quote (t->label);
55 if (ips) cout << " -- " << obtain_ip (t);
56 cout << "\n";
57 }
58 else {
59 cout << as_string (L(t));
60 if (ips) cout << " -- " << obtain_ip (t);
61 cout << "\n";
62 for (i=0; i<N(t); i++)
63 stretched_print (t[i], ips, indent+1);
64 }
65 }
66
67 tm_ostream&
operator <<(tm_ostream & out,observer o)68 operator << (tm_ostream& out, observer o) {
69 out << "<observer";
70 if (is_nil (o)) out << " null";
71 else o->print (out);
72 out << ">";
73 return out;
74 }
75
76 /******************************************************************************
77 * Routines for modifying trees
78 *******************************************************************************
79 * 1) The "inserting modifications" (insert, split and insert_node) invoke
80 * the observers call-back routines after the actual modification and
81 * "assigning and deleting modifications" (assign, remove, join,
82 * assign_node and remove_node) before the actual modification.
83 * set_cursor does not make any modifications in the tree
84 * 2) The split and join modifications pass the joined tree
85 * at position pos as an additional argument to the call-back routines.
86 * 3) They also admit variant call back routines for the split/join nodes.
87 ******************************************************************************/
88
89 static void
simplify(observer & obs)90 simplify (observer& obs) {
91 if (is_nil (obs)) return;
92 observer& o1= obs->get_child (0);
93 observer& o2= obs->get_child (1);
94 if (!is_nil (o1) || !is_nil (o2)) {
95 simplify (o1);
96 simplify (o2);
97 obs= list_observer (o1, o2);
98 }
99 }
100
101 static void
detach(tree & ref,tree closest,bool right)102 detach (tree& ref, tree closest, bool right) {
103 if (!is_nil (ref->obs)) {
104 ref->obs->notify_detach (ref, closest, right);
105 simplify (ref->obs);
106 }
107 if (is_compound (ref)) {
108 int i, n= N(ref);
109 for (i=0; i<n; i++)
110 detach (ref[i], closest, right);
111 }
112 }
113
114 void
raw_assign(tree & ref,tree t)115 raw_assign (tree& ref, tree t) {
116 // cout << "Assign " << ref << " := " << t << "\n";
117 modification mod= mod_assign (path (), t);
118 if (!is_nil (ref->obs)) {
119 ref->obs->announce (ref, mod);
120 ref->obs->notify_assign (ref, t);
121 simplify (ref->obs);
122 }
123 if (is_compound (ref)) {
124 int i, n= N(ref), mid= (n+1)>>1;
125 for (i=0; i<n; i++)
126 detach (ref[i], t, i >= mid);
127 }
128 ref= t;
129 if (!is_nil (ref->obs)) ref->obs->done (ref, mod);
130 // stretched_print (ref, true, 1);
131 // consistency_check ();
132 }
133
134 void
raw_insert(tree & ref,int pos,tree t)135 raw_insert (tree& ref, int pos, tree t) {
136 // cout << "Insert " << ref << " += " << t << " at " << pos << "\n";
137 modification mod= mod_insert (path (), pos, t);
138 if (!is_nil (ref->obs))
139 ref->obs->announce (ref, mod);
140 if (is_atomic (ref) && is_atomic (t))
141 ref->label= ref->label (0, pos) *t->label* ref->label (pos, N(ref->label));
142 else {
143 int i, n= N(ref), nr= N(t);
144 AR(ref)->resize (n+nr);
145 for (i=n-1; i>=pos; i--)
146 ref[i+nr]= ref[i];
147 for (i=0; i<nr; i++)
148 ref[pos+i]= t[i];
149 }
150 if (!is_nil (ref->obs)) {
151 ref->obs->notify_insert (ref, pos, is_atomic (t)? N(t->label): N(t));
152 simplify (ref->obs);
153 }
154 if (!is_nil (ref->obs)) ref->obs->done (ref, mod);
155 // stretched_print (ref, true, 1);
156 // consistency_check ();
157 }
158
159 void
raw_remove(tree & ref,int pos,int nr)160 raw_remove (tree& ref, int pos, int nr) {
161 // cout << "Remove " << ref << " -= " << nr << " at " << pos << "\n";
162 modification mod= mod_remove (path (), pos, nr);
163 if (nr == 0) return;
164 if (!is_nil (ref->obs)) {
165 ref->obs->announce (ref, mod);
166 ref->obs->notify_remove (ref, pos, nr);
167 simplify (ref->obs);
168 }
169 if (is_compound (ref)) {
170 int i, n= N(ref), end= pos+nr, mid= (pos+end+1) >> 1;
171 for (i=pos; i<mid; i++)
172 if (pos == 0) detach (ref[i], ref, false);
173 else detach (ref[i], ref[pos-1], true);
174 for (; i<end; i++)
175 if (end == n) detach (ref[i], ref, true);
176 else detach (ref[i], ref[pos+nr], false);
177 }
178
179 if (is_atomic (ref))
180 ref->label= ref->label (0, pos) * ref->label (pos+nr, N(ref->label));
181 else {
182 int i, n= N(ref)-nr;
183 for (i=pos; i<n; i++)
184 ref[i]= ref[i+nr];
185 AR(ref)->resize (n);
186 }
187 if (!is_nil (ref->obs)) ref->obs->done (ref, mod);
188 // stretched_print (ref, true, 1);
189 // consistency_check ();
190 }
191
192 void
raw_split(tree & ref,int pos,int at)193 raw_split (tree& ref, int pos, int at) {
194 // cout << "Split " << ref << " at " << pos << ", " << at << "\n";
195 modification mod= mod_split (path (), pos, at);
196 if (!is_nil (ref->obs))
197 ref->obs->announce (ref, mod);
198 tree t= ref[pos], t1, t2;
199 if (is_atomic (ref[pos])) {
200 t1= ref[pos]->label (0, at);
201 t2= ref[pos]->label (at, N(ref[pos]->label));
202 }
203 else {
204 t1= ref[pos] (0, at);
205 t2= ref[pos] (at, N(ref[pos]));
206 }
207 int i, n= N(ref);
208 AR(ref)->resize (n+1);
209 for (i=n; i>(pos+1); i--)
210 ref[i]= ref[i-1];
211 ref[pos ]= t1;
212 ref[pos+1]= t2;
213
214 if (!is_nil (ref->obs)) {
215 ref->obs->notify_split (ref, pos, t);
216 simplify (ref->obs);
217 }
218 if (!is_nil (t->obs)) {
219 t->obs->notify_var_split (t, t1, t2);
220 simplify (t->obs);
221 }
222 if (!is_nil (ref->obs)) ref->obs->done (ref, mod);
223 // stretched_print (ref, true, 1);
224 // consistency_check ();
225 }
226
227 void
raw_join(tree & ref,int pos)228 raw_join (tree& ref, int pos) {
229 // cout << "Join " << ref << " at " << pos << "\n";
230 // the following code is added for security
231 if (is_atomic (ref[pos]) && (!is_atomic (ref[pos+1])))
232 insert_node (ref[pos], 0, tree (L(ref[pos+1])));
233 if (is_atomic (ref[pos+1]) && (!is_atomic (ref[pos])))
234 insert_node (ref[pos+1], 0, tree (L(ref[pos])));
235 // end security code
236
237 modification mod= mod_join (path (), pos);
238 if (!is_nil (ref->obs)) ref->obs->announce (ref, mod);
239 tree t1= ref[pos], t2= ref[pos+1], t;
240 int offset= is_atomic (ref)? N(t1->label): N(t1);
241 if (is_atomic (t1) && is_atomic (t2)) t= t1->label * t2->label;
242 else t= t1 * t2;
243 if (!is_nil (ref->obs)) ref->obs->notify_join (ref, pos, t);
244 if (!is_nil (t1->obs)) {
245 t1->obs->notify_var_join (t1, t, 0);
246 simplify (t1->obs);
247 }
248 if (!is_nil (t2->obs)) {
249 t2->obs->notify_var_join (t2, t, offset);
250 simplify (t2->obs);
251 }
252 ref[pos]= t;
253
254 int i, n= N(ref)-1;
255 for (i=pos+1; i<n; i++)
256 ref[i]= ref[i+1];
257 AR(ref)->resize (n);
258 if (!is_nil (ref->obs)) ref->obs->done (ref, mod);
259 // stretched_print (ref, true, 1);
260 // consistency_check ();
261 }
262
263 void
raw_assign_node(tree & ref,tree_label op)264 raw_assign_node (tree& ref, tree_label op) {
265 // cout << "Assign node " << ref << " : " << tree (op) << "\n";
266 modification mod= mod_assign_node (path (), op);
267 if (!is_nil (ref->obs)) {
268 ref->obs->announce (ref, mod);
269 ref->obs->notify_assign_node (ref, op);
270 simplify (ref->obs);
271 }
272 LR (ref)= op;
273 if (!is_nil (ref->obs)) ref->obs->done (ref, mod);
274 // stretched_print (ref, true, 1);
275 // consistency_check ();
276 }
277
278 void
raw_insert_node(tree & ref,int pos,tree t)279 raw_insert_node (tree& ref, int pos, tree t) {
280 // cout << "Insert node " << ref << " : " << t << " at " << pos << "\n";
281 modification mod= mod_insert_node (path (), pos, t);
282 if (!is_nil (ref->obs)) ref->obs->announce (ref, mod);
283 int i, n= N(t);
284 tree r (t, n+1);
285 for (i=0; i<pos; i++) r[i]= t[i];
286 r[pos]= ref;
287 for (i=pos; i<n; i++) r[i+1]= t[i];
288 ref= r;
289 if (!is_nil (ref[pos]->obs)) {
290 ref[pos]->obs->notify_insert_node (ref, pos);
291 simplify (ref[pos]->obs);
292 }
293 if (!is_nil (ref->obs)) ref->obs->done (ref, mod);
294 // stretched_print (ref, true, 1);
295 // consistency_check ();
296 }
297
298 void
raw_remove_node(tree & ref,int pos)299 raw_remove_node (tree& ref, int pos) {
300 // cout << "Remove node " << ref << " : " << pos << "\n";
301 modification mod= mod_remove_node (path (), pos);
302 if (!is_nil (ref->obs)) {
303 ref->obs->announce (ref, mod);
304 ref->obs->notify_remove_node (ref, pos);
305 simplify (ref->obs);
306 }
307 for (int i=0; i<N(ref); i++)
308 if (i < pos) detach (ref[i], ref[pos], false);
309 else if (i > pos) detach (ref[i], ref[pos], true);
310 ref= ref[pos];
311 if (!is_nil (ref->obs)) ref->obs->done (ref, mod);
312 // stretched_print (ref, true, 1);
313 // consistency_check ();
314 }
315
316 void
raw_set_cursor(tree & ref,int pos,tree data)317 raw_set_cursor (tree& ref, int pos, tree data) {
318 // cout << "Set cursor " << ref << " : " << pos << ", " << data << "\n";
319 modification mod= mod_set_cursor (path (), pos, data);
320 if (!is_nil (ref->obs)) {
321 ref->obs->announce (ref, mod);
322 ref->obs->notify_set_cursor (ref, pos, data);
323 simplify (ref->obs);
324 }
325 if (!is_nil (ref->obs)) ref->obs->done (ref, mod);
326 // stretched_print (ref, true, 1);
327 // consistency_check ();
328 }
329
330 void
raw_apply(tree & t,modification mod)331 raw_apply (tree& t, modification mod) {
332 ASSERT (is_applicable (t, mod), "invalid modification");
333 switch (mod->k) {
334 case MOD_ASSIGN:
335 raw_assign (subtree (t, root (mod)), mod->t);
336 break;
337 case MOD_INSERT:
338 raw_insert (subtree (t, root (mod)), index (mod), mod->t);
339 break;
340 case MOD_REMOVE:
341 raw_remove (subtree (t, root (mod)), index (mod), argument (mod));
342 break;
343 case MOD_SPLIT:
344 raw_split (subtree (t, root (mod)), index (mod), argument (mod));
345 break;
346 case MOD_JOIN:
347 raw_join (subtree (t, root (mod)), index (mod));
348 break;
349 case MOD_ASSIGN_NODE:
350 raw_assign_node (subtree (t, root (mod)), L (mod));
351 break;
352 case MOD_INSERT_NODE:
353 raw_insert_node (subtree (t, root (mod)), argument (mod), mod->t);
354 break;
355 case MOD_REMOVE_NODE:
356 raw_remove_node (subtree (t, root (mod)), index (mod));
357 break;
358 case MOD_SET_CURSOR:
359 raw_set_cursor (subtree (t, root (mod)), index (mod), mod->t);
360 break;
361 }
362 packrat_invalid_colors= true;
363 }
364
365 /******************************************************************************
366 * Wrappers which take into account mirroring
367 ******************************************************************************/
368
369 bool busy_modifying= false;
370 bool busy_versioning= false;
371 static bool is_busy= false;
372 static list<path> busy_paths;
373 static list<modification> upcoming;
374
375 bool
busy_path(path p)376 busy_path (path p) {
377 for (list<path> l= busy_paths; !is_nil (l); l= l->next)
378 if (l->item <= p) return true;
379 return false;
380 }
381
382 bool
busy_tree(tree & ref)383 busy_tree (tree& ref) {
384 path ip= obtain_ip (ref);
385 if (ip_attached (ip)) return busy_path (reverse (ip));
386 else return true;
387 }
388
389 void
apply(tree & ref,modification mod)390 apply (tree& ref, modification mod) {
391 if (!is_applicable (ref, mod)) {
392 failed_error << "mod= " << mod << "\n";
393 failed_error << "ref= " << ref << "\n";
394 FAILED ("invalid modification");
395 }
396 path ip= obtain_ip (ref);
397 path rp= reverse (ip);
398 path p = rp * root (mod);
399 if (busy_modifying) raw_apply (ref, mod);
400 else if (is_busy) {
401 if (ip_attached (ip) && !busy_path (p)) {
402 //cout << "Postpone " << (reverse (ip) * mod) << "\n";
403 busy_paths= busy_paths * p;
404 upcoming = upcoming * (reverse (ip) * mod);
405 }
406 }
407 else {
408 if (!ip_attached (ip)) raw_apply (ref, mod);
409 else {
410 is_busy= true;
411 busy_paths= list<path> (p);
412 upcoming = list<modification> (reverse (ip) * mod);
413 while (!is_nil (upcoming)) {
414 //cout << "Handle " << upcoming->item << "\n";
415 raw_apply (the_et, upcoming->item);
416 //cout << "Done " << upcoming->item << "\n";
417 upcoming= upcoming->next;
418 }
419 busy_paths= list<path> ();
420 is_busy= false;
421 if (has_subtree (the_et, rp))
422 ref= subtree (the_et, rp);
423 }
424 }
425 }
426
427 void
assign(tree & ref,tree t)428 assign (tree& ref, tree t) {
429 apply (ref, mod_assign (path (), t));
430 }
431
432 void
insert(tree & ref,int pos,tree t)433 insert (tree& ref, int pos, tree t) {
434 apply (ref, mod_insert (path (), pos, t));
435 }
436
437 void
remove(tree & ref,int pos,int nr)438 remove (tree& ref, int pos, int nr) {
439 apply (ref, mod_remove (path (), pos, nr));
440 }
441
442 void
split(tree & ref,int pos,int at)443 split (tree& ref, int pos, int at) {
444 apply (ref, mod_split (path (), pos, at));
445 }
446
447 void
join(tree & ref,int pos)448 join (tree& ref, int pos) {
449 apply (ref, mod_join (path (), pos));
450 }
451
452 void
assign_node(tree & ref,tree_label op)453 assign_node (tree& ref, tree_label op) {
454 apply (ref, mod_assign_node (path (), op));
455 }
456
457 void
insert_node(tree & ref,int pos,tree t)458 insert_node (tree& ref, int pos, tree t) {
459 apply (ref, mod_insert_node (path (), pos, t));
460 }
461
462 void
remove_node(tree & ref,int pos)463 remove_node (tree& ref, int pos) {
464 apply (ref, mod_remove_node (path (), pos));
465 }
466
467 void
set_cursor(tree & ref,int pos,tree data)468 set_cursor (tree& ref, int pos, tree data) {
469 apply (ref, mod_set_cursor (path (), pos, data));
470 }
471
472 void
touch(tree & ref)473 touch (tree& ref) {
474 //cout << "Touch " << ref << "\n";
475 if (!is_nil (ref->obs))
476 ref->obs->touched (ref, path ());
477 }
478
479 /******************************************************************************
480 * Wrappers for trees given by a path
481 ******************************************************************************/
482
483 void
assign(path p,tree t)484 assign (path p, tree t) {
485 assign (subtree (the_et, p), t);
486 }
487
488 void
insert(path p,tree ins)489 insert (path p, tree ins) {
490 insert (subtree (the_et, path_up (p)), last_item (p), ins);
491 }
492
493 void
remove(path p,int nr)494 remove (path p, int nr) {
495 remove (subtree (the_et, path_up (p)), last_item (p), nr);
496 }
497
498 void
split(path p)499 split (path p) {
500 tree& st= subtree (the_et, path_up (path_up (p)));
501 int l1= last_item (path_up (p));
502 int l2= last_item (p);
503 split (st, l1, l2);
504 }
505
506 void
join(path p)507 join (path p) {
508 join (subtree (the_et, path_up (p)), last_item (p));
509 }
510
511 void
assign_node(path p,tree_label op)512 assign_node (path p, tree_label op) {
513 assign_node (subtree (the_et, p), op);
514 }
515
516 void
insert_node(path p,tree ins)517 insert_node (path p, tree ins) {
518 insert_node (subtree (the_et, path_up (p)), last_item (p), ins);
519 }
520
521 void
remove_node(path p)522 remove_node (path p) {
523 remove_node (subtree (the_et, path_up (p)), last_item (p));
524 }
525
526 void
set_cursor(path p,tree data)527 set_cursor (path p, tree data) {
528 if (is_inside (the_et, p))
529 set_cursor (subtree (the_et, path_up (p)), last_item (p), data);
530 else
531 cout << "TeXmacs] warning: invalid cursor position " << p << "\n";
532 }
533
534 void
touch(path p)535 touch (path p) {
536 touch (subtree (the_et, p));
537 }
538
539 /******************************************************************************
540 * Default virtual routines
541 ******************************************************************************/
542
543 void
announce(tree & ref,modification mod)544 observer_rep::announce (tree& ref, modification mod) {
545 // cout << "Modify: " << mod << "\n";
546 switch (mod->k) {
547 case MOD_ASSIGN:
548 announce_assign (ref, mod->p, mod->t);
549 break;
550 case MOD_INSERT:
551 announce_insert (ref, mod->p, mod->t);
552 break;
553 case MOD_REMOVE:
554 announce_remove (ref, path_up (mod->p), last_item (mod->p));
555 break;
556 case MOD_SPLIT:
557 announce_split (ref, mod->p);
558 break;
559 case MOD_JOIN:
560 announce_join (ref, mod->p);
561 break;
562 case MOD_ASSIGN_NODE:
563 announce_assign_node (ref, mod->p, L(mod->t));
564 break;
565 case MOD_INSERT_NODE:
566 announce_insert_node (ref, mod->p, mod->t);
567 break;
568 case MOD_REMOVE_NODE:
569 announce_remove_node (ref, mod->p);
570 break;
571 case MOD_SET_CURSOR:
572 announce_set_cursor (ref, mod->p, mod->t);
573 break;
574 }
575 }
576
577 void
done(tree & ref,modification mod)578 observer_rep::done (tree& ref, modification mod) {
579 (void) ref; (void) mod;
580 }
581
582 void
touched(tree & ref,path p)583 observer_rep::touched (tree& ref, path p) {
584 (void) ref; (void) p;
585 }
586
587 void
announce_assign(tree & ref,path p,tree t)588 observer_rep::announce_assign (tree& ref, path p, tree t) {
589 (void) ref; (void) p; (void) t;
590 }
591
592 void
announce_insert(tree & ref,path p,tree ins)593 observer_rep::announce_insert (tree& ref, path p, tree ins) {
594 (void) ref; (void) p; (void) ins;
595 }
596
597 void
announce_remove(tree & ref,path p,int nr)598 observer_rep::announce_remove (tree& ref, path p, int nr) {
599 (void) ref; (void) p; (void) nr;
600 }
601
602 void
announce_split(tree & ref,path p)603 observer_rep::announce_split (tree& ref, path p) {
604 (void) ref; (void) p;
605 }
606
607 void
announce_join(tree & ref,path p)608 observer_rep::announce_join (tree& ref, path p) {
609 (void) ref; (void) p;
610 }
611
612 void
announce_assign_node(tree & ref,path p,tree_label op)613 observer_rep::announce_assign_node (tree& ref, path p, tree_label op) {
614 (void) ref; (void) p; (void) op;
615 }
616
617 void
announce_insert_node(tree & ref,path p,tree ins)618 observer_rep::announce_insert_node (tree& ref, path p, tree ins) {
619 (void) ref; (void) p; (void) ins;
620 }
621
622 void
announce_remove_node(tree & ref,path p)623 observer_rep::announce_remove_node (tree& ref, path p) {
624 (void) ref; (void) p;
625 }
626
627 void
announce_set_cursor(tree & ref,path p,tree data)628 observer_rep::announce_set_cursor (tree& ref, path p, tree data) {
629 (void) ref; (void) p; (void) data;
630 }
631
632 void
notify_assign(tree & ref,tree t)633 observer_rep::notify_assign (tree& ref, tree t) {
634 (void) ref; (void) t;
635 }
636
637 void
notify_insert(tree & ref,int pos,int nr)638 observer_rep::notify_insert (tree& ref, int pos, int nr) {
639 (void) ref; (void) pos; (void) nr;
640 }
641
642 void
notify_remove(tree & ref,int pos,int nr)643 observer_rep::notify_remove (tree& ref, int pos, int nr) {
644 (void) ref; (void) pos; (void) nr;
645 }
646
647 void
notify_split(tree & ref,int pos,tree prev)648 observer_rep::notify_split (tree& ref, int pos, tree prev) {
649 (void) ref; (void) pos; (void) prev;
650 }
651
652 void
notify_var_split(tree & ref,tree t1,tree t2)653 observer_rep::notify_var_split (tree& ref, tree t1, tree t2) {
654 (void) ref; (void) t1; (void) t2;
655 }
656
657 void
notify_join(tree & ref,int pos,tree next)658 observer_rep::notify_join (tree& ref, int pos, tree next) {
659 (void) ref; (void) pos; (void) next;
660 }
661
662 void
notify_var_join(tree & ref,tree t,int offset)663 observer_rep::notify_var_join (tree& ref, tree t, int offset) {
664 (void) ref; (void) t; (void) offset;
665 }
666
667 void
notify_assign_node(tree & ref,tree_label op)668 observer_rep::notify_assign_node (tree& ref, tree_label op) {
669 (void) ref; (void) op;
670 }
671
672 void
notify_insert_node(tree & ref,int pos)673 observer_rep::notify_insert_node (tree& ref, int pos) {
674 (void) ref; (void) pos;
675 }
676
677 void
notify_remove_node(tree & ref,int pos)678 observer_rep::notify_remove_node (tree& ref, int pos) {
679 (void) ref; (void) pos;
680 }
681
682 void
notify_set_cursor(tree & ref,int pos,tree data)683 observer_rep::notify_set_cursor (tree& ref, int pos, tree data) {
684 (void) ref; (void) pos; (void) data;
685 }
686
687 void
notify_detach(tree & ref,tree closest,bool right)688 observer_rep::notify_detach (tree& ref, tree closest, bool right) {
689 (void) ref; (void) closest; (void) right;
690 }
691
692 bool
get_ip(path & ip)693 observer_rep::get_ip (path& ip) {
694 (void) ip;
695 return false;
696 }
697
698 bool
set_ip(path ip)699 observer_rep::set_ip (path ip) {
700 (void) ip;
701 return false;
702 }
703
704 bool
get_position(tree & t,int & index)705 observer_rep::get_position (tree& t, int& index) {
706 (void) t; (void) index;
707 return false;
708 }
709
710 bool
set_position(tree t,int index)711 observer_rep::set_position (tree t, int index) {
712 (void) t; (void) index;
713 return false;
714 }
715
716 observer&
get_child(int which)717 observer_rep::get_child (int which) {
718 (void) which;
719 return nil_observer;
720 }
721
722 list<observer>
get_tree_pointers()723 observer_rep::get_tree_pointers () {
724 return list<observer> ();
725 }
726
727 bool
get_tree(tree & t)728 observer_rep::get_tree (tree& t) {
729 (void) t;
730 return false;
731 }
732
733 bool
get_contents(int kind,blackbox & bb)734 observer_rep::get_contents (int kind, blackbox& bb) {
735 (void) kind; (void) bb;
736 return false;
737 }
738
739 bool
set_highlight(int lan,int col,int start,int end)740 observer_rep::set_highlight (int lan, int col, int start, int end) {
741 (void) col; (void) start; (void) end; (void) lan;
742 return false;
743 }
744
745 bool
get_highlight(int lan,array<int> & cols)746 observer_rep::get_highlight (int lan, array<int>& cols) {
747 (void) lan; (void) cols; return false;
748 }
749