~ubuntu-branches/ubuntu/quantal/texmacs/quantal

« back to all changes in this revision

Viewing changes to src/Kernel/Abstractions/observer.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Atsuhito KOHDA, Kamaraju Kusumanchi, kohda
  • Date: 2009-04-26 19:35:14 UTC
  • mfrom: (1.1.10 upstream) (4.1.4 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090426193514-9yo3oggdslgdls4b
Tags: 1:1.0.7.2-1
[Kamaraju Kusumanchi <kamaraju@gmail.com>]
* New upstream release
* texmacs crashes if /usr/share/texmacs/TeXmacs/misc/pixmaps/unknown.ps
  is not present. Do not remove it. (Closes: #484073, #497021)
* update patches 03_mupad.dpatch, 04_axiom.dpatch, 11-desktop-file.dpatch
* fix the mime problem in gnome. Thanks to Andrea Gamba for the fix.
[kohda]
* Refined a fix for the mime problem in gnome a bit.
* Try to fix /bin/sh problem (debian/fixsh) but it is not complete fix yet.
* Try to fix hard coded settings for ipa fonts(patches/09_ipa.dpatch), 
  especially for Debian where no ipa fonts exist yet.
* Fixed obsolete Build-Depends: changed libltdl3-dev to 
  libltdl-dev | libltdl7-dev (the latter for Ubuntu?)

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
* DESCRIPTION: Observers of trees
5
5
* COPYRIGHT  : (C) 1999  Joris van der Hoeven
6
6
*******************************************************************************
7
 
* This software falls under the GNU general public license and comes WITHOUT
8
 
* ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details.
9
 
* If you don't have this file, write to the Free Software Foundation, Inc.,
10
 
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
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>.
11
10
******************************************************************************/
12
11
 
13
 
#include "tree.hpp"
14
 
#include "path.hpp"
 
12
#include "modification.hpp"
15
13
#include "analyze.hpp"
 
14
#include "hashmap.hpp"
16
15
 
17
16
#define DETACHED (-5)
18
17
 
19
18
observer nil_observer;
 
19
extern tree the_et;
20
20
 
21
21
/******************************************************************************
22
22
* Debugging facilities
23
23
******************************************************************************/
24
24
 
25
 
extern tree the_et;
26
 
 
27
25
static void
28
26
consistency_check (tree t, path ip) {
29
27
  if (obtain_ip (t) != ip)
111
109
}
112
110
 
113
111
void
114
 
assign (tree& ref, tree t) {
 
112
raw_assign (tree& ref, tree t) {
115
113
  // cout << "Assign " << ref << " := " << t << "\n";
 
114
  modification mod= mod_assign (path (), t);
116
115
  if (!is_nil (ref->obs)) {
 
116
    ref->obs->announce (ref, mod);
117
117
    ref->obs->notify_assign (ref, t);
118
118
    simplify (ref->obs);
119
119
  }
123
123
      detach (ref[i], t, i >= mid);
124
124
  }
125
125
  ref= t;
 
126
  if (!is_nil (ref->obs)) ref->obs->done (ref, mod);
126
127
  // stretched_print (ref, true, 1);
127
128
  // consistency_check ();
128
129
}
129
130
 
130
131
void
131
 
insert (tree& ref, int pos, tree t) {
 
132
raw_insert (tree& ref, int pos, tree t) {
132
133
  // cout << "Insert " << ref << " += " << t << " at " << pos << "\n";
 
134
  modification mod= mod_insert (path (), pos, t);
 
135
  if (!is_nil (ref->obs))
 
136
    ref->obs->announce (ref, mod);
133
137
  if (is_atomic (ref) && is_atomic (t))
134
138
    ref->label= ref->label (0, pos) *t->label* ref->label (pos, N(ref->label));
135
139
  else {
144
148
    ref->obs->notify_insert (ref, pos, is_atomic (t)? N(t->label): N(t));
145
149
    simplify (ref->obs);
146
150
  }
 
151
  if (!is_nil (ref->obs)) ref->obs->done (ref, mod);
147
152
  // stretched_print (ref, true, 1);
148
153
  // consistency_check ();
149
154
}
150
155
 
151
156
void
152
 
remove (tree& ref, int pos, int nr) {
 
157
raw_remove (tree& ref, int pos, int nr) {
153
158
  // cout << "Remove " << ref << " -= " << nr << " at " << pos << "\n";
 
159
  modification mod= mod_remove (path (), pos, nr);
 
160
  if (nr == 0) return;
154
161
  if (!is_nil (ref->obs)) {
 
162
    ref->obs->announce (ref, mod);
155
163
    ref->obs->notify_remove (ref, pos, nr);
156
164
    simplify (ref->obs);
157
165
  }
173
181
      ref[i]= ref[i+nr];
174
182
    AR(ref)->resize (n);
175
183
  }
 
184
  if (!is_nil (ref->obs)) ref->obs->done (ref, mod);
176
185
  // stretched_print (ref, true, 1);
177
186
  // consistency_check ();
178
187
}
179
188
 
180
189
void
181
 
split (tree& ref, int pos, int at) {
 
190
raw_split (tree& ref, int pos, int at) {
182
191
  // cout << "Split " << ref << " at " << pos << ", " << at << "\n";
 
192
  modification mod= mod_split (path (), pos, at);
 
193
  if (!is_nil (ref->obs))
 
194
    ref->obs->announce (ref, mod);
183
195
  tree t= ref[pos], t1, t2;
184
196
  if (is_atomic (ref[pos])) {    
185
197
    t1= ref[pos]->label (0, at);
204
216
    t->obs->notify_var_split (t, t1, t2);
205
217
    simplify (t->obs);
206
218
  }
 
219
  if (!is_nil (ref->obs)) ref->obs->done (ref, mod);
207
220
  // stretched_print (ref, true, 1);
208
221
  // consistency_check ();
209
222
}
210
223
 
211
224
void
212
 
join (tree& ref, int pos) {
 
225
raw_join (tree& ref, int pos) {
213
226
  // cout << "Join " << ref << " at " << pos << "\n";
214
227
  // the following code is added for security
215
228
  if (is_atomic (ref[pos]) && (!is_atomic (ref[pos+1])))
218
231
    insert_node (ref[pos+1], 0, tree (L(ref[pos])));
219
232
  // end security code
220
233
 
 
234
  modification mod= mod_join (path (), pos);
 
235
  if (!is_nil (ref->obs)) ref->obs->announce (ref, mod);
221
236
  tree t1= ref[pos], t2= ref[pos+1], t;
222
237
  int offset= is_atomic (ref)? N(t1->label): N(t1);
223
238
  if (is_atomic (t1) && is_atomic (t2)) t= t1->label * t2->label;
237
252
  for (i=pos+1; i<n; i++)
238
253
    ref[i]= ref[i+1];
239
254
  AR(ref)->resize (n);
 
255
  if (!is_nil (ref->obs)) ref->obs->done (ref, mod);
240
256
  // stretched_print (ref, true, 1);
241
257
  // consistency_check ();
242
258
}
243
259
 
244
260
void
245
 
assign_node (tree& ref, tree_label op) {
 
261
raw_assign_node (tree& ref, tree_label op) {
246
262
  // cout << "Assign node " << ref << " : " << tree (op) << "\n";
 
263
  modification mod= mod_assign_node (path (), op);
247
264
  if (!is_nil (ref->obs)) {
 
265
    ref->obs->announce (ref, mod);
248
266
    ref->obs->notify_assign_node (ref, op);
249
267
    simplify (ref->obs);
250
268
  }
251
269
  LR (ref)= op;
 
270
  if (!is_nil (ref->obs)) ref->obs->done (ref, mod);
252
271
  // stretched_print (ref, true, 1);
253
272
  // consistency_check ();
254
273
}
255
274
 
256
275
void
257
 
insert_node (tree& ref, int pos, tree t) {
 
276
raw_insert_node (tree& ref, int pos, tree t) {
258
277
  // cout << "Insert node " << ref << " : " << t << " at " << pos << "\n";
 
278
  modification mod= mod_insert_node (path (), pos, t);
 
279
  if (!is_nil (ref->obs)) ref->obs->announce (ref, mod);
259
280
  int i, n= N(t);
260
281
  tree r (t, n+1);
261
282
  for (i=0; i<pos; i++) r[i]= t[i];
266
287
    ref[pos]->obs->notify_insert_node (ref, pos);
267
288
    simplify (ref[pos]->obs);
268
289
  }
 
290
  if (!is_nil (ref->obs)) ref->obs->done (ref, mod);
269
291
  // stretched_print (ref, true, 1);
270
292
  // consistency_check ();
271
293
}
272
294
 
273
295
void
274
 
remove_node (tree& ref, int pos) {
 
296
raw_remove_node (tree& ref, int pos) {
275
297
  // cout << "Remove node " << ref << " : " << pos << "\n";
 
298
  modification mod= mod_remove_node (path (), pos);
276
299
  if (!is_nil (ref->obs)) {
 
300
    ref->obs->announce (ref, mod);
277
301
    ref->obs->notify_remove_node (ref, pos);
278
302
    simplify (ref->obs);
279
303
  }
281
305
    if (i < pos) detach (ref[i], ref[pos], false);
282
306
    else if (i > pos) detach (ref[i], ref[pos], true);
283
307
  ref= ref[pos];
 
308
  if (!is_nil (ref->obs)) ref->obs->done (ref, mod);
284
309
  // stretched_print (ref, true, 1);
285
310
  // consistency_check ();
286
311
}
287
312
 
 
313
void
 
314
raw_apply (tree& t, modification mod) {
 
315
  ASSERT (is_applicable (t, mod), "invalid modification");
 
316
  switch (mod->k) {
 
317
  case MOD_ASSIGN:
 
318
    raw_assign (subtree (t, root (mod)), mod->t);
 
319
    break;
 
320
  case MOD_INSERT:
 
321
    raw_insert (subtree (t, root (mod)), index (mod), mod->t);
 
322
    break;
 
323
  case MOD_REMOVE:
 
324
    raw_remove (subtree (t, root (mod)), index (mod), argument (mod));
 
325
    break;
 
326
  case MOD_SPLIT:
 
327
    raw_split (subtree (t, root (mod)), index (mod), argument (mod));
 
328
    break;
 
329
  case MOD_JOIN:
 
330
    raw_join (subtree (t, root (mod)), index (mod));
 
331
    break;
 
332
  case MOD_ASSIGN_NODE:
 
333
    raw_assign_node (subtree (t, root (mod)), L (mod));
 
334
    break;
 
335
  case MOD_INSERT_NODE:
 
336
    raw_insert_node (subtree (t, root (mod)), argument (mod), mod->t);
 
337
    break;
 
338
  case MOD_REMOVE_NODE:
 
339
    raw_remove_node (subtree (t, root (mod)), index (mod));
 
340
    break;
 
341
  }
 
342
}
 
343
 
 
344
/******************************************************************************
 
345
* Wrappers which take into account mirroring
 
346
******************************************************************************/
 
347
 
 
348
bool versioning_busy= false;
 
349
static bool is_busy= false;
 
350
static list<path> busy_paths;
 
351
static list<modification> upcoming;
 
352
 
 
353
bool
 
354
busy_path (path p) {
 
355
  for (list<path> l= busy_paths; !is_nil (l); l= l->next)
 
356
    if (l->item <= p) return true;
 
357
  return false;
 
358
}
 
359
 
 
360
bool
 
361
busy_tree (tree& ref) {
 
362
  path ip= obtain_ip (ref);
 
363
  if (ip_attached (ip)) return busy_path (reverse (ip));
 
364
  else return true;
 
365
}
 
366
 
 
367
void
 
368
apply (tree& ref, modification mod) {
 
369
  ASSERT (is_applicable (ref, mod), "invalid modification");
 
370
  path ip= obtain_ip (ref);
 
371
  path p = reverse (ip) * root (mod);
 
372
  if (versioning_busy) raw_apply (ref, mod);
 
373
  else if (is_busy) {
 
374
    if (ip_attached (ip) && !busy_path (p)) {
 
375
      //cout << "Postpone " << (reverse (ip) * mod) << "\n";
 
376
      busy_paths= busy_paths * p;
 
377
      upcoming  = upcoming * (reverse (ip) * mod);
 
378
    }
 
379
  }
 
380
  else {
 
381
    if (!ip_attached (ip)) raw_apply (ref, mod);
 
382
    else {
 
383
      is_busy= true;
 
384
      busy_paths= list<path> (p);
 
385
      upcoming  = list<modification> (reverse (ip) * mod);
 
386
      while (!is_nil (upcoming)) {
 
387
        //cout << "Handle " << upcoming->item << "\n";
 
388
        raw_apply (the_et, upcoming->item);
 
389
        //cout << "Done " << upcoming->item << "\n";
 
390
        upcoming= upcoming->next;
 
391
      }
 
392
      busy_paths= list<path> ();
 
393
      is_busy= false;
 
394
    }
 
395
  }
 
396
}
 
397
 
 
398
void
 
399
assign (tree& ref, tree t) {
 
400
  apply (ref, mod_assign (path (), t));
 
401
}
 
402
 
 
403
void
 
404
insert (tree& ref, int pos, tree t) {
 
405
  apply (ref, mod_insert (path (), pos, t));
 
406
}
 
407
 
 
408
void
 
409
remove (tree& ref, int pos, int nr) {
 
410
  apply (ref, mod_remove (path (), pos, nr));
 
411
}
 
412
 
 
413
void
 
414
split (tree& ref, int pos, int at) {
 
415
  apply (ref, mod_split (path (), pos, at));
 
416
}
 
417
 
 
418
void
 
419
join (tree& ref, int pos) {
 
420
  apply (ref, mod_join (path (), pos));
 
421
}
 
422
 
 
423
void
 
424
assign_node (tree& ref, tree_label op) {
 
425
  apply (ref, mod_assign_node (path (), op));
 
426
}
 
427
 
 
428
void
 
429
insert_node (tree& ref, int pos, tree t) {
 
430
  apply (ref, mod_insert_node (path (), pos, t));
 
431
}
 
432
 
 
433
void
 
434
remove_node (tree& ref, int pos) {
 
435
  apply (ref, mod_remove_node (path (), pos));
 
436
}
 
437
 
 
438
/******************************************************************************
 
439
* Wrappers for trees given by a path
 
440
******************************************************************************/
 
441
 
 
442
void
 
443
assign (path p, tree t) {
 
444
  assign (subtree (the_et, p), t);
 
445
}
 
446
 
 
447
void
 
448
insert (path p, tree ins) {
 
449
  insert (subtree (the_et, path_up (p)), last_item (p), ins);
 
450
}
 
451
 
 
452
void
 
453
remove (path p, int nr) {
 
454
  remove (subtree (the_et, path_up (p)), last_item (p), nr);
 
455
}
 
456
 
 
457
void
 
458
split (path p) {
 
459
  tree& st= subtree (the_et, path_up (path_up (p)));
 
460
  int   l1= last_item (path_up (p));
 
461
  int   l2= last_item (p);
 
462
  split (st, l1, l2);  
 
463
}
 
464
 
 
465
void
 
466
join (path p) {
 
467
  join (subtree (the_et, path_up (p)), last_item (p));
 
468
}
 
469
 
 
470
void
 
471
assign_node (path p, tree_label op) {
 
472
  assign_node (subtree (the_et, p), op);
 
473
}
 
474
 
 
475
void
 
476
insert_node (path p, tree ins) {
 
477
  insert_node (subtree (the_et, path_up (p)), last_item (p), ins);
 
478
}
 
479
 
 
480
void
 
481
remove_node (path p) {
 
482
  remove_node (subtree (the_et, path_up (p)), last_item (p));
 
483
}
 
484
 
288
485
/******************************************************************************
289
486
* Default virtual routines
290
487
******************************************************************************/
291
488
 
 
489
void
 
490
observer_rep::announce (tree& ref, modification mod) {
 
491
  // cout << "Modify: " << mod << "\n";
 
492
  switch (mod->k) {
 
493
  case MOD_ASSIGN:
 
494
    announce_assign (ref, mod->p, mod->t);
 
495
    break;
 
496
  case MOD_INSERT:
 
497
    announce_insert (ref, mod->p, mod->t);
 
498
    break;
 
499
  case MOD_REMOVE:
 
500
    announce_remove (ref, path_up (mod->p), last_item (mod->p));
 
501
    break;
 
502
  case MOD_SPLIT:
 
503
    announce_split (ref, mod->p);
 
504
    break;
 
505
  case MOD_JOIN:
 
506
    announce_join (ref, mod->p);
 
507
    break;
 
508
  case MOD_ASSIGN_NODE:
 
509
    announce_assign_node (ref, mod->p, L(mod->t));
 
510
    break;
 
511
  case MOD_INSERT_NODE:
 
512
    announce_insert_node (ref, mod->p, mod->t);
 
513
    break;
 
514
  case MOD_REMOVE_NODE:
 
515
    announce_remove_node (ref, mod->p);
 
516
    break;
 
517
  }
 
518
}
 
519
 
 
520
void
 
521
observer_rep::done (tree& ref, modification mod) {
 
522
  (void) ref; (void) mod;
 
523
}
 
524
 
 
525
void
 
526
observer_rep::announce_assign (tree& ref, path p, tree t) {
 
527
  (void) ref; (void) p; (void) t;
 
528
}
 
529
 
 
530
void
 
531
observer_rep::announce_insert (tree& ref, path p, tree ins) {
 
532
  (void) ref; (void) p; (void) ins;
 
533
}
 
534
 
 
535
void
 
536
observer_rep::announce_remove (tree& ref, path p, int nr) {
 
537
  (void) ref; (void) p; (void) nr;
 
538
}
 
539
 
 
540
void
 
541
observer_rep::announce_split (tree& ref, path p) {
 
542
  (void) ref; (void) p;
 
543
}
 
544
 
 
545
void
 
546
observer_rep::announce_join (tree& ref, path p) {
 
547
  (void) ref; (void) p;
 
548
}
 
549
 
 
550
void
 
551
observer_rep::announce_assign_node (tree& ref, path p, tree_label op) {
 
552
  (void) ref; (void) p; (void) op;
 
553
}
 
554
 
 
555
void
 
556
observer_rep::announce_insert_node (tree& ref, path p, tree ins) {
 
557
  (void) ref; (void) p; (void) ins;
 
558
}
 
559
 
 
560
void
 
561
observer_rep::announce_remove_node (tree& ref, path p) {
 
562
  (void) ref; (void) p;
 
563
}
 
564
 
 
565
void
 
566
observer_rep::notify_assign (tree& ref, tree t) {
 
567
  (void) ref; (void) t;
 
568
}
 
569
 
 
570
void
 
571
observer_rep::notify_insert (tree& ref, int pos, int nr) {
 
572
  (void) ref; (void) pos; (void) nr;
 
573
}
 
574
 
 
575
void
 
576
observer_rep::notify_remove (tree& ref, int pos, int nr) {
 
577
  (void) ref; (void) pos; (void) nr;
 
578
}
 
579
 
 
580
void
 
581
observer_rep::notify_split (tree& ref, int pos, tree prev) {
 
582
  (void) ref; (void) pos; (void) prev;
 
583
}
 
584
 
 
585
void
 
586
observer_rep::notify_var_split (tree& ref, tree t1, tree t2) {
 
587
  (void) ref; (void) t1; (void) t2;
 
588
}
 
589
 
 
590
void
 
591
observer_rep::notify_join (tree& ref, int pos, tree next) {
 
592
  (void) ref; (void) pos; (void) next;
 
593
}
 
594
 
 
595
void
 
596
observer_rep::notify_var_join (tree& ref, tree t, int offset) {
 
597
  (void) ref; (void) t; (void) offset;
 
598
}
 
599
 
 
600
void
 
601
observer_rep::notify_assign_node (tree& ref, tree_label op) {
 
602
  (void) ref; (void) op;
 
603
}
 
604
 
 
605
void
 
606
observer_rep::notify_insert_node (tree& ref, int pos) {
 
607
  (void) ref; (void) pos;
 
608
}
 
609
 
 
610
void
 
611
observer_rep::notify_remove_node (tree& ref, int pos) {
 
612
  (void) ref; (void) pos;
 
613
}
 
614
 
 
615
void
 
616
observer_rep::notify_detach (tree& ref, tree closest, bool right) {
 
617
  (void) ref; (void) closest; (void) right;
 
618
}
 
619
 
292
620
bool
293
621
observer_rep::get_ip (path& ip) {
294
622
  (void) ip;