Back to index

texmacs  1.0.7.15
observer.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : observer.cpp
00004 * DESCRIPTION: Observers of trees
00005 * COPYRIGHT  : (C) 1999  Joris van der Hoeven
00006 *******************************************************************************
00007 * This software falls under the GNU general public license version 3 or later.
00008 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00009 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00010 ******************************************************************************/
00011 
00012 #include "modification.hpp"
00013 #include "analyze.hpp"
00014 #include "hashmap.hpp"
00015 #include "blackbox.hpp"
00016 
00017 #define DETACHED (-5)
00018 
00019 observer nil_observer;
00020 extern tree the_et;
00021 extern bool packrat_invalid_colors;
00022 
00023 /******************************************************************************
00024 * Debugging facilities
00025 ******************************************************************************/
00026 
00027 static void
00028 consistency_check (tree t, path ip) {
00029   if (obtain_ip (t) != ip)
00030     cout << "Wrong ip] " << t << " " << obtain_ip (t)
00031         << " instead of " << ip << "\n";
00032   if (is_compound (t)) {
00033     int i, n= N(t);
00034     for (i=0; i<n; i++) {
00035       //if (!strong_equal (ip, obtain_ip (t[i])->next))
00036       if (obtain_ip (t) != obtain_ip (t[i])->next)
00037        cout << "Bad node] " << t << " " << obtain_ip (t) << " #" << i << "\n";
00038       consistency_check (t[i], path (i, ip));
00039     }
00040   }
00041 }
00042 
00043 void
00044 consistency_check () {
00045   consistency_check (the_et, path ());
00046   cout << HRULE;
00047 }
00048 
00049 void
00050 stretched_print (tree t, bool ips, int indent) {
00051   int i;
00052   for (i=0; i<indent; i++) cout << "  ";
00053   if (is_atomic (t)) {
00054     cout << raw_quote (t->label);
00055     if (ips) cout << " -- " << obtain_ip (t);
00056     cout << "\n";
00057   }
00058   else {
00059     cout << as_string (L(t));
00060     if (ips) cout << " -- " << obtain_ip (t);
00061     cout << "\n";    
00062     for (i=0; i<N(t); i++)
00063       stretched_print (t[i], ips, indent+1);
00064   }
00065 }
00066 
00067 tm_ostream&
00068 operator << (tm_ostream& out, observer o) {
00069   out << "<observer";
00070   if (is_nil (o)) out << " null";
00071   else o->print (out);
00072   out << ">";
00073   return out;
00074 }
00075 
00076 /******************************************************************************
00077 * Routines for modifying trees
00078 *******************************************************************************
00079 * 1) The "inserting modifications" (insert, split and insert_node) invoke
00080 *    the observers call-back routines after the actual modification and
00081 *    "assigning and deleting modifications" (assign, remove, join,
00082 *    assign_node and remove_node) before the actual modification.
00083 *    set_cursor does not make any modifications in the tree
00084 * 2) The split and join modifications pass the joined tree
00085 *    at position pos as an additional argument to the call-back routines.
00086 * 3) They also admit variant call back routines for the split/join nodes.
00087 ******************************************************************************/
00088 
00089 static void
00090 simplify (observer& obs) {
00091   if (is_nil (obs)) return;
00092   observer& o1= obs->get_child (0);
00093   observer& o2= obs->get_child (1);  
00094   if (!is_nil (o1) || !is_nil (o2)) {
00095     simplify (o1);
00096     simplify (o2);
00097     obs= list_observer (o1, o2);
00098   }
00099 }
00100 
00101 static void
00102 detach (tree& ref, tree closest, bool right) {
00103   if (!is_nil (ref->obs)) {
00104     ref->obs->notify_detach (ref, closest, right);
00105     simplify (ref->obs);
00106   }
00107   if (is_compound (ref)) {
00108     int i, n= N(ref);
00109     for (i=0; i<n; i++)
00110       detach (ref[i], closest, right);
00111   }
00112 }
00113 
00114 void
00115 raw_assign (tree& ref, tree t) {
00116   // cout << "Assign " << ref << " := " << t << "\n";
00117   modification mod= mod_assign (path (), t);
00118   if (!is_nil (ref->obs)) {
00119     ref->obs->announce (ref, mod);
00120     ref->obs->notify_assign (ref, t);
00121     simplify (ref->obs);
00122   }
00123   if (is_compound (ref)) {
00124     int i, n= N(ref), mid= (n+1)>>1;
00125     for (i=0; i<n; i++)
00126       detach (ref[i], t, i >= mid);
00127   }
00128   ref= t;
00129   if (!is_nil (ref->obs)) ref->obs->done (ref, mod);
00130   // stretched_print (ref, true, 1);
00131   // consistency_check ();
00132 }
00133 
00134 void
00135 raw_insert (tree& ref, int pos, tree t) {
00136   // cout << "Insert " << ref << " += " << t << " at " << pos << "\n";
00137   modification mod= mod_insert (path (), pos, t);
00138   if (!is_nil (ref->obs))
00139     ref->obs->announce (ref, mod);
00140   if (is_atomic (ref) && is_atomic (t))
00141     ref->label= ref->label (0, pos) *t->label* ref->label (pos, N(ref->label));
00142   else {
00143     int i, n= N(ref), nr= N(t);
00144     AR(ref)->resize (n+nr);
00145     for (i=n-1; i>=pos; i--)
00146       ref[i+nr]= ref[i];
00147     for (i=0; i<nr; i++)
00148       ref[pos+i]= t[i];
00149   }
00150   if (!is_nil (ref->obs)) {
00151     ref->obs->notify_insert (ref, pos, is_atomic (t)? N(t->label): N(t));
00152     simplify (ref->obs);
00153   }
00154   if (!is_nil (ref->obs)) ref->obs->done (ref, mod);
00155   // stretched_print (ref, true, 1);
00156   // consistency_check ();
00157 }
00158 
00159 void
00160 raw_remove (tree& ref, int pos, int nr) {
00161   // cout << "Remove " << ref << " -= " << nr << " at " << pos << "\n";
00162   modification mod= mod_remove (path (), pos, nr);
00163   if (nr == 0) return;
00164   if (!is_nil (ref->obs)) {
00165     ref->obs->announce (ref, mod);
00166     ref->obs->notify_remove (ref, pos, nr);
00167     simplify (ref->obs);
00168   }
00169   if (is_compound (ref)) {
00170     int i, n= N(ref), end= pos+nr, mid= (pos+end+1) >> 1;
00171     for (i=pos; i<mid; i++)
00172       if (pos == 0) detach (ref[i], ref, false);
00173       else detach (ref[i], ref[pos-1], true);
00174     for (; i<end; i++)
00175       if (end == n) detach (ref[i], ref, true);
00176       else detach (ref[i], ref[pos+nr], false);
00177   }
00178 
00179   if (is_atomic (ref))
00180     ref->label= ref->label (0, pos) * ref->label (pos+nr, N(ref->label));
00181   else {
00182     int i, n= N(ref)-nr;
00183     for (i=pos; i<n; i++)
00184       ref[i]= ref[i+nr];
00185     AR(ref)->resize (n);
00186   }
00187   if (!is_nil (ref->obs)) ref->obs->done (ref, mod);
00188   // stretched_print (ref, true, 1);
00189   // consistency_check ();
00190 }
00191 
00192 void
00193 raw_split (tree& ref, int pos, int at) {
00194   // cout << "Split " << ref << " at " << pos << ", " << at << "\n";
00195   modification mod= mod_split (path (), pos, at);
00196   if (!is_nil (ref->obs))
00197     ref->obs->announce (ref, mod);
00198   tree t= ref[pos], t1, t2;
00199   if (is_atomic (ref[pos])) {    
00200     t1= ref[pos]->label (0, at);
00201     t2= ref[pos]->label (at, N(ref[pos]->label));
00202   }
00203   else {
00204     t1= ref[pos] (0, at);
00205     t2= ref[pos] (at, N(ref[pos]));
00206   }
00207   int i, n= N(ref);
00208   AR(ref)->resize (n+1);
00209   for (i=n; i>(pos+1); i--)
00210     ref[i]= ref[i-1];
00211   ref[pos  ]= t1;
00212   ref[pos+1]= t2;
00213 
00214   if (!is_nil (ref->obs)) {
00215     ref->obs->notify_split (ref, pos, t);
00216     simplify (ref->obs);
00217   }
00218   if (!is_nil (t->obs)) {
00219     t->obs->notify_var_split (t, t1, t2);
00220     simplify (t->obs);
00221   }
00222   if (!is_nil (ref->obs)) ref->obs->done (ref, mod);
00223   // stretched_print (ref, true, 1);
00224   // consistency_check ();
00225 }
00226 
00227 void
00228 raw_join (tree& ref, int pos) {
00229   // cout << "Join " << ref << " at " << pos << "\n";
00230   // the following code is added for security
00231   if (is_atomic (ref[pos]) && (!is_atomic (ref[pos+1])))
00232     insert_node (ref[pos], 0, tree (L(ref[pos+1])));
00233   if (is_atomic (ref[pos+1]) && (!is_atomic (ref[pos])))
00234     insert_node (ref[pos+1], 0, tree (L(ref[pos])));
00235   // end security code
00236 
00237   modification mod= mod_join (path (), pos);
00238   if (!is_nil (ref->obs)) ref->obs->announce (ref, mod);
00239   tree t1= ref[pos], t2= ref[pos+1], t;
00240   int offset= is_atomic (ref)? N(t1->label): N(t1);
00241   if (is_atomic (t1) && is_atomic (t2)) t= t1->label * t2->label;
00242   else t= t1 * t2;
00243   if (!is_nil (ref->obs)) ref->obs->notify_join (ref, pos, t);
00244   if (!is_nil (t1->obs)) {
00245     t1->obs->notify_var_join (t1, t, 0);
00246     simplify (t1->obs);
00247   }
00248   if (!is_nil (t2->obs)) {
00249     t2->obs->notify_var_join (t2, t, offset);
00250     simplify (t2->obs);
00251   }
00252   ref[pos]= t;
00253 
00254   int i, n= N(ref)-1;
00255   for (i=pos+1; i<n; i++)
00256     ref[i]= ref[i+1];
00257   AR(ref)->resize (n);
00258   if (!is_nil (ref->obs)) ref->obs->done (ref, mod);
00259   // stretched_print (ref, true, 1);
00260   // consistency_check ();
00261 }
00262 
00263 void
00264 raw_assign_node (tree& ref, tree_label op) {
00265   // cout << "Assign node " << ref << " : " << tree (op) << "\n";
00266   modification mod= mod_assign_node (path (), op);
00267   if (!is_nil (ref->obs)) {
00268     ref->obs->announce (ref, mod);
00269     ref->obs->notify_assign_node (ref, op);
00270     simplify (ref->obs);
00271   }
00272   LR (ref)= op;
00273   if (!is_nil (ref->obs)) ref->obs->done (ref, mod);
00274   // stretched_print (ref, true, 1);
00275   // consistency_check ();
00276 }
00277 
00278 void
00279 raw_insert_node (tree& ref, int pos, tree t) {
00280   // cout << "Insert node " << ref << " : " << t << " at " << pos << "\n";
00281   modification mod= mod_insert_node (path (), pos, t);
00282   if (!is_nil (ref->obs)) ref->obs->announce (ref, mod);
00283   int i, n= N(t);
00284   tree r (t, n+1);
00285   for (i=0; i<pos; i++) r[i]= t[i];
00286   r[pos]= ref;
00287   for (i=pos; i<n; i++) r[i+1]= t[i];
00288   ref= r;
00289   if (!is_nil (ref[pos]->obs)) {
00290     ref[pos]->obs->notify_insert_node (ref, pos);
00291     simplify (ref[pos]->obs);
00292   }
00293   if (!is_nil (ref->obs)) ref->obs->done (ref, mod);
00294   // stretched_print (ref, true, 1);
00295   // consistency_check ();
00296 }
00297 
00298 void
00299 raw_remove_node (tree& ref, int pos) {
00300   // cout << "Remove node " << ref << " : " << pos << "\n";
00301   modification mod= mod_remove_node (path (), pos);
00302   if (!is_nil (ref->obs)) {
00303     ref->obs->announce (ref, mod);
00304     ref->obs->notify_remove_node (ref, pos);
00305     simplify (ref->obs);
00306   }
00307   for (int i=0; i<N(ref); i++)
00308     if (i < pos) detach (ref[i], ref[pos], false);
00309     else if (i > pos) detach (ref[i], ref[pos], true);
00310   ref= ref[pos];
00311   if (!is_nil (ref->obs)) ref->obs->done (ref, mod);
00312   // stretched_print (ref, true, 1);
00313   // consistency_check ();
00314 }
00315 
00316 void
00317 raw_set_cursor (tree& ref, int pos, tree data) {
00318   // cout << "Set cursor " << ref << " : " << pos << ", " << data << "\n";
00319   modification mod= mod_set_cursor (path (), pos, data);
00320   if (!is_nil (ref->obs)) {
00321     ref->obs->announce (ref, mod);
00322     ref->obs->notify_set_cursor (ref, pos, data);
00323     simplify (ref->obs);
00324   }
00325   if (!is_nil (ref->obs)) ref->obs->done (ref, mod);
00326   // stretched_print (ref, true, 1);
00327   // consistency_check ();
00328 }
00329 
00330 void
00331 raw_apply (tree& t, modification mod) {
00332   ASSERT (is_applicable (t, mod), "invalid modification");
00333   switch (mod->k) {
00334   case MOD_ASSIGN:
00335     raw_assign (subtree (t, root (mod)), mod->t);
00336     break;
00337   case MOD_INSERT:
00338     raw_insert (subtree (t, root (mod)), index (mod), mod->t);
00339     break;
00340   case MOD_REMOVE:
00341     raw_remove (subtree (t, root (mod)), index (mod), argument (mod));
00342     break;
00343   case MOD_SPLIT:
00344     raw_split (subtree (t, root (mod)), index (mod), argument (mod));
00345     break;
00346   case MOD_JOIN:
00347     raw_join (subtree (t, root (mod)), index (mod));
00348     break;
00349   case MOD_ASSIGN_NODE:
00350     raw_assign_node (subtree (t, root (mod)), L (mod));
00351     break;
00352   case MOD_INSERT_NODE:
00353     raw_insert_node (subtree (t, root (mod)), argument (mod), mod->t);
00354     break;
00355   case MOD_REMOVE_NODE:
00356     raw_remove_node (subtree (t, root (mod)), index (mod));
00357     break;
00358   case MOD_SET_CURSOR:
00359     raw_set_cursor (subtree (t, root (mod)), index (mod), mod->t);
00360     break;
00361   }
00362   packrat_invalid_colors= true;
00363 }
00364 
00365 /******************************************************************************
00366 * Wrappers which take into account mirroring
00367 ******************************************************************************/
00368 
00369 bool versioning_busy= false;
00370 static bool is_busy= false;
00371 static list<path> busy_paths;
00372 static list<modification> upcoming;
00373 
00374 bool
00375 busy_path (path p) {
00376   for (list<path> l= busy_paths; !is_nil (l); l= l->next)
00377     if (l->item <= p) return true;
00378   return false;
00379 }
00380 
00381 bool
00382 busy_tree (tree& ref) {
00383   path ip= obtain_ip (ref);
00384   if (ip_attached (ip)) return busy_path (reverse (ip));
00385   else return true;
00386 }
00387 
00388 void
00389 apply (tree& ref, modification mod) {
00390   if (!is_applicable (ref, mod)) {
00391     cout << "mod= " << mod << "\n";
00392     cout << "ref= " << ref << "\n";
00393     ASSERT (is_applicable (ref, mod), "invalid modification");
00394   }
00395   path ip= obtain_ip (ref);
00396   path rp= reverse (ip);
00397   path p = rp * root (mod);
00398   if (versioning_busy) raw_apply (ref, mod);
00399   else if (is_busy) {
00400     if (ip_attached (ip) && !busy_path (p)) {
00401       //cout << "Postpone " << (reverse (ip) * mod) << "\n";
00402       busy_paths= busy_paths * p;
00403       upcoming  = upcoming * (reverse (ip) * mod);
00404     }
00405   }
00406   else {
00407     if (!ip_attached (ip)) raw_apply (ref, mod);
00408     else {
00409       is_busy= true;
00410       busy_paths= list<path> (p);
00411       upcoming  = list<modification> (reverse (ip) * mod);
00412       while (!is_nil (upcoming)) {
00413        //cout << "Handle " << upcoming->item << "\n";
00414        raw_apply (the_et, upcoming->item);
00415        //cout << "Done " << upcoming->item << "\n";
00416        upcoming= upcoming->next;
00417       }
00418       busy_paths= list<path> ();
00419       is_busy= false;
00420       if (has_subtree (the_et, rp))
00421        ref= subtree (the_et, rp);
00422     }
00423   }
00424 }
00425 
00426 void
00427 assign (tree& ref, tree t) {
00428   apply (ref, mod_assign (path (), t));
00429 }
00430 
00431 void
00432 insert (tree& ref, int pos, tree t) {
00433   apply (ref, mod_insert (path (), pos, t));
00434 }
00435 
00436 void
00437 remove (tree& ref, int pos, int nr) {
00438   apply (ref, mod_remove (path (), pos, nr));
00439 }
00440 
00441 void
00442 split (tree& ref, int pos, int at) {
00443   apply (ref, mod_split (path (), pos, at));
00444 }
00445 
00446 void
00447 join (tree& ref, int pos) {
00448   apply (ref, mod_join (path (), pos));
00449 }
00450 
00451 void
00452 assign_node (tree& ref, tree_label op) {
00453   apply (ref, mod_assign_node (path (), op));
00454 }
00455 
00456 void
00457 insert_node (tree& ref, int pos, tree t) {
00458   apply (ref, mod_insert_node (path (), pos, t));
00459 }
00460 
00461 void
00462 remove_node (tree& ref, int pos) {
00463   apply (ref, mod_remove_node (path (), pos));
00464 }
00465 
00466 void
00467 set_cursor (tree& ref, int pos, tree data) {
00468   apply (ref, mod_set_cursor (path (), pos, data));
00469 }
00470 
00471 void
00472 touch (tree& ref) {
00473   //cout << "Touch " << ref << "\n";
00474   if (!is_nil (ref->obs))
00475     ref->obs->touched (ref, path ());
00476 }
00477 
00478 /******************************************************************************
00479 * Wrappers for trees given by a path
00480 ******************************************************************************/
00481 
00482 void
00483 assign (path p, tree t) {
00484   assign (subtree (the_et, p), t);
00485 }
00486 
00487 void
00488 insert (path p, tree ins) {
00489   insert (subtree (the_et, path_up (p)), last_item (p), ins);
00490 }
00491 
00492 void
00493 remove (path p, int nr) {
00494   remove (subtree (the_et, path_up (p)), last_item (p), nr);
00495 }
00496 
00497 void
00498 split (path p) {
00499   tree& st= subtree (the_et, path_up (path_up (p)));
00500   int   l1= last_item (path_up (p));
00501   int   l2= last_item (p);
00502   split (st, l1, l2);  
00503 }
00504 
00505 void
00506 join (path p) {
00507   join (subtree (the_et, path_up (p)), last_item (p));
00508 }
00509 
00510 void
00511 assign_node (path p, tree_label op) {
00512   assign_node (subtree (the_et, p), op);
00513 }
00514 
00515 void
00516 insert_node (path p, tree ins) {
00517   insert_node (subtree (the_et, path_up (p)), last_item (p), ins);
00518 }
00519 
00520 void
00521 remove_node (path p) {
00522   remove_node (subtree (the_et, path_up (p)), last_item (p));
00523 }
00524 
00525 void
00526 set_cursor (path p, tree data) {
00527   if (is_inside (the_et, p))
00528     set_cursor (subtree (the_et, path_up (p)), last_item (p), data);
00529   else
00530     cout << "TeXmacs] warning: invalid cursor position " << p << "\n";
00531 }
00532 
00533 void
00534 touch (path p) {
00535   touch (subtree (the_et, p));
00536 }
00537 
00538 /******************************************************************************
00539 * Default virtual routines
00540 ******************************************************************************/
00541 
00542 void
00543 observer_rep::announce (tree& ref, modification mod) {
00544   // cout << "Modify: " << mod << "\n";
00545   switch (mod->k) {
00546   case MOD_ASSIGN:
00547     announce_assign (ref, mod->p, mod->t);
00548     break;
00549   case MOD_INSERT:
00550     announce_insert (ref, mod->p, mod->t);
00551     break;
00552   case MOD_REMOVE:
00553     announce_remove (ref, path_up (mod->p), last_item (mod->p));
00554     break;
00555   case MOD_SPLIT:
00556     announce_split (ref, mod->p);
00557     break;
00558   case MOD_JOIN:
00559     announce_join (ref, mod->p);
00560     break;
00561   case MOD_ASSIGN_NODE:
00562     announce_assign_node (ref, mod->p, L(mod->t));
00563     break;
00564   case MOD_INSERT_NODE:
00565     announce_insert_node (ref, mod->p, mod->t);
00566     break;
00567   case MOD_REMOVE_NODE:
00568     announce_remove_node (ref, mod->p);
00569     break;
00570   case MOD_SET_CURSOR:
00571     announce_set_cursor (ref, mod->p, mod->t);
00572     break;
00573   }
00574 }
00575 
00576 void
00577 observer_rep::done (tree& ref, modification mod) {
00578   (void) ref; (void) mod;
00579 }
00580 
00581 void
00582 observer_rep::touched (tree& ref, path p) {
00583   (void) ref; (void) p;
00584 }
00585 
00586 void
00587 observer_rep::announce_assign (tree& ref, path p, tree t) {
00588   (void) ref; (void) p; (void) t;
00589 }
00590 
00591 void
00592 observer_rep::announce_insert (tree& ref, path p, tree ins) {
00593   (void) ref; (void) p; (void) ins;
00594 }
00595 
00596 void
00597 observer_rep::announce_remove (tree& ref, path p, int nr) {
00598   (void) ref; (void) p; (void) nr;
00599 }
00600 
00601 void
00602 observer_rep::announce_split (tree& ref, path p) {
00603   (void) ref; (void) p;
00604 }
00605 
00606 void
00607 observer_rep::announce_join (tree& ref, path p) {
00608   (void) ref; (void) p;
00609 }
00610 
00611 void
00612 observer_rep::announce_assign_node (tree& ref, path p, tree_label op) {
00613   (void) ref; (void) p; (void) op;
00614 }
00615 
00616 void
00617 observer_rep::announce_insert_node (tree& ref, path p, tree ins) {
00618   (void) ref; (void) p; (void) ins;
00619 }
00620 
00621 void
00622 observer_rep::announce_remove_node (tree& ref, path p) {
00623   (void) ref; (void) p;
00624 }
00625 
00626 void
00627 observer_rep::announce_set_cursor (tree& ref, path p, tree data) {
00628   (void) ref; (void) p; (void) data;
00629 }
00630 
00631 void
00632 observer_rep::notify_assign (tree& ref, tree t) {
00633   (void) ref; (void) t;
00634 }
00635 
00636 void
00637 observer_rep::notify_insert (tree& ref, int pos, int nr) {
00638   (void) ref; (void) pos; (void) nr;
00639 }
00640 
00641 void
00642 observer_rep::notify_remove (tree& ref, int pos, int nr) {
00643   (void) ref; (void) pos; (void) nr;
00644 }
00645 
00646 void
00647 observer_rep::notify_split (tree& ref, int pos, tree prev) {
00648   (void) ref; (void) pos; (void) prev;
00649 }
00650 
00651 void
00652 observer_rep::notify_var_split (tree& ref, tree t1, tree t2) {
00653   (void) ref; (void) t1; (void) t2;
00654 }
00655 
00656 void
00657 observer_rep::notify_join (tree& ref, int pos, tree next) {
00658   (void) ref; (void) pos; (void) next;
00659 }
00660 
00661 void
00662 observer_rep::notify_var_join (tree& ref, tree t, int offset) {
00663   (void) ref; (void) t; (void) offset;
00664 }
00665 
00666 void
00667 observer_rep::notify_assign_node (tree& ref, tree_label op) {
00668   (void) ref; (void) op;
00669 }
00670 
00671 void
00672 observer_rep::notify_insert_node (tree& ref, int pos) {
00673   (void) ref; (void) pos;
00674 }
00675 
00676 void
00677 observer_rep::notify_remove_node (tree& ref, int pos) {
00678   (void) ref; (void) pos;
00679 }
00680 
00681 void
00682 observer_rep::notify_set_cursor (tree& ref, int pos, tree data) {
00683   (void) ref; (void) pos; (void) data;
00684 }
00685 
00686 void
00687 observer_rep::notify_detach (tree& ref, tree closest, bool right) {
00688   (void) ref; (void) closest; (void) right;
00689 }
00690 
00691 bool
00692 observer_rep::get_ip (path& ip) {
00693   (void) ip;
00694   return false;
00695 }
00696 
00697 bool
00698 observer_rep::set_ip (path ip) {
00699   (void) ip;
00700   return false;
00701 }
00702 
00703 bool
00704 observer_rep::get_position (tree& t, int& index) {
00705   (void) t; (void) index;
00706   return false;
00707 }
00708 
00709 bool
00710 observer_rep::set_position (tree t, int index) {
00711   (void) t; (void) index;
00712   return false;
00713 }
00714 
00715 observer&
00716 observer_rep::get_child (int which) {
00717   (void) which;
00718   return nil_observer;
00719 }
00720 
00721 list<observer>
00722 observer_rep::get_tree_pointers () {
00723   return list<observer> ();
00724 }
00725 
00726 bool
00727 observer_rep::get_tree (tree& t) {
00728   (void) t;
00729   return false;
00730 }
00731 
00732 bool
00733 observer_rep::get_contents (int kind, blackbox& bb) {
00734   (void) kind; (void) bb;
00735   return false;
00736 }
00737 
00738 bool
00739 observer_rep::set_highlight (int lan, int col, int start, int end) {
00740   (void) col; (void) start; (void) end; (void) lan;
00741   return false;
00742 }
00743 
00744 bool
00745 observer_rep::get_highlight (int lan, array<int>& cols) {
00746   (void) lan; (void) cols; return false;
00747 }