1 
2 /******************************************************************************
3 * MODULE     : glue.cpp
4 * DESCRIPTION: Glue for linking TeXmacs commands to scheme
5 * COPYRIGHT  : (C) 1999-2011  Joris van der Hoeven and Massimiliano Gubinelli
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 "glue.hpp"
13 
14 #include "promise.hpp"
15 #include "tree.hpp"
16 #include "drd_mode.hpp"
17 #include "tree_search.hpp"
18 #include "modification.hpp"
19 #include "patch.hpp"
20 
21 #include "boxes.hpp"
22 #include "editor.hpp"
23 #include "universal.hpp"
24 #include "convert.hpp"
25 #include "file.hpp"
26 #include "iterator.hpp"
27 #include "Freetype/tt_tools.hpp"
28 #include "Database/database.hpp"
29 #include "Sqlite3/sqlite3.hpp"
30 #include "Updater/tm_updater.hpp"
31 
32 tmscm
blackboxP(tmscm t)33 blackboxP (tmscm t) {
34   bool b= tmscm_is_blackbox (t);
35   return bool_to_tmscm (b);
36 }
37 
38 #if 0
39 template<class T> tmscm box_to_tmscm (T o) {
40   return blackbox_to_tmscm (close_box<T> (o)); }
41 template<class T> T tmscm_to_box (tmscm obj) {
42   return open_box<T>(tmscm_to_blackbox (obj));  }
43 template<class T> tmscm cmp_box (tmscm o1, tmscm o2) {
44   return bool_to_tmscm (tmscm_to_box<T> (o1) == tmscm_to_box<T> (o2)); }
45 template<class T> tmscm boxP (tmscm t) {
46   bool b= tmscm_is_blackbox (t) &&
47           (type_box (blackboxvalue(t)) == type_helper<T>::id);
48   return bool_to_tmscm (b);
49 }
50 #endif
51 
52 /******************************************************************************
53 * Miscellaneous routines for use by glue only
54 ******************************************************************************/
55 
56 string
texmacs_version(string which)57 texmacs_version (string which) {
58   if (which == "tgz") return TM_DEVEL;
59   if (which == "rpm") return TM_DEVEL_RELEASE;
60   if (which == "stgz") return TM_STABLE;
61   if (which == "srpm") return TM_STABLE_RELEASE;
62   if (which == "devel") return TM_DEVEL;
63   if (which == "stable") return TM_STABLE;
64   if (which == "devel-release") return TM_DEVEL_RELEASE;
65   if (which == "stable-release") return TM_STABLE_RELEASE;
66   return TEXMACS_VERSION;
67 }
68 
69 void
set_fast_environments(bool b)70 set_fast_environments (bool b) {
71   enable_fastenv= b;
72 }
73 
74 void
win32_display(string s)75 win32_display (string s) {
76   cout << s;
77   cout.flush ();
78 }
79 
80 void
tm_output(string s)81 tm_output (string s) {
82   cout << s;
83   cout.flush ();
84 }
85 
86 void
tm_errput(string s)87 tm_errput (string s) {
88   cerr << s;
89   cerr.flush ();
90 }
91 
92 void
cpp_error()93 cpp_error () {
94   //char *np= 0; *np= 1;
95   FAILED ("an error occurred");
96 }
97 
98 array<int>
get_bounding_rectangle(tree t)99 get_bounding_rectangle (tree t) {
100   editor ed= get_current_editor ();
101   rectangle wr= ed -> get_window_extents ();
102   path p= reverse (obtain_ip (t));
103   selection sel= ed->search_selection (p * start (t), p * end (t));
104   SI sz= ed->get_pixel_size ();
105   double sf= ((double) sz) / 256.0;
106   rectangle selr= least_upper_bound (sel->rs) / sf;
107   rectangle r= translate (selr, wr->x1, wr->y2);
108   array<int> ret;
109   ret << (r->x1) << (r->y1) << (r->x2) << (r->y2);
110   //ret << (r->x1/PIXEL) << (r->y1/PIXEL) << (r->x2/PIXEL) << (r->y2/PIXEL);
111   return ret;
112 }
113 
114 bool
supports_native_pdf()115 supports_native_pdf () {
116 #ifdef PDF_RENDERER
117   return true;
118 #else
119   return false;
120 #endif
121 }
122 
123 bool
supports_ghostscript()124 supports_ghostscript () {
125 #ifdef USE_GS
126   return true;
127 #else
128   return false;
129 #endif
130 }
131 
132 bool
is_busy_versioning()133 is_busy_versioning () {
134   return busy_versioning;
135 }
136 
137 /******************************************************************************
138 * Redirections
139 ******************************************************************************/
140 
141 void
cout_buffer()142 cout_buffer () {
143   cout.buffer ();
144 }
145 
146 string
cout_unbuffer()147 cout_unbuffer () {
148   return cout.unbuffer ();
149 }
150 
151 /******************************************************************************
152 * Basic assertions
153 ******************************************************************************/
154 
155 #define TMSCM_ASSERT_STRING(s,arg,rout) \
156 TMSCM_ASSERT (tmscm_is_string (s), s, arg, rout)
157 #define TMSCM_ASSERT_BOOL(flag,arg,rout) \
158 TMSCM_ASSERT (tmscm_is_bool (flag), flag, arg, rout)
159 #define TMSCM_ASSERT_INT(i,arg,rout) \
160 TMSCM_ASSERT (tmscm_is_int (i), i, arg, rout);
161 #define TMSCM_ASSERT_DOUBLE(i,arg,rout) \
162   TMSCM_ASSERT (tmscm_is_double (i), i, arg, rout);
163 //TMSCM_ASSERT (SCM_REALP (i), i, arg, rout);
164 #define TMSCM_ASSERT_URL(u,arg,rout) \
165 TMSCM_ASSERT (tmscm_is_url (u) || tmscm_is_string (u), u, arg, rout)
166 #define TMSCM_ASSERT_MODIFICATION(m,arg,rout) \
167 TMSCM_ASSERT (tmscm_is_modification (m), m, arg, rout)
168 #define TMSCM_ASSERT_PATCH(p,arg,rout) \
169 TMSCM_ASSERT (tmscm_is_patch (p), p, arg, rout)
170 #define TMSCM_ASSERT_BLACKBOX(t,arg,rout) \
171 TMSCM_ASSERT (tmscm_is_blackbox (t), t, arg, rout)
172 #define TMSCM_ASSERT_SYMBOL(s,arg,rout) \
173   TMSCM_ASSERT (tmscm_is_symbol (s), s, arg, rout)
174 //TMSCM_ASSERT (SCM_NFALSEP (tmscm_symbol_p (s)), s, arg, rout)
175 
176 #define TMSCM_ASSERT_OBJECT(a,b,c)
177 // no check
178 
179 /******************************************************************************
180 * Tree labels
181 ******************************************************************************/
182 
183 #define TMSCM_ASSERT_TREE_LABEL(p,arg,rout) TMSCM_ASSERT_SYMBOL(p,arg,rout)
184 
185 tmscm
tree_label_to_tmscm(tree_label l)186 tree_label_to_tmscm (tree_label l) {
187   string s= as_string (l);
188   return symbol_to_tmscm (s);
189 }
190 
191 tree_label
tmscm_to_tree_label(tmscm p)192 tmscm_to_tree_label (tmscm p) {
193   string s= tmscm_to_symbol (p);
194   return make_tree_label (s);
195 }
196 
197 /******************************************************************************
198 * Trees
199 ******************************************************************************/
200 
201 #define TMSCM_ASSERT_TREE(t,arg,rout) TMSCM_ASSERT (tmscm_is_tree (t), t, arg, rout)
202 
203 
204 bool
tmscm_is_tree(tmscm u)205 tmscm_is_tree (tmscm u) {
206   return (tmscm_is_blackbox (u) &&
207          (type_box (tmscm_to_blackbox(u)) == type_helper<tree>::id));
208 }
209 
210 tmscm
tree_to_tmscm(tree o)211 tree_to_tmscm (tree o) {
212   return blackbox_to_tmscm (close_box<tree> (o));
213 }
214 
215 tree
tmscm_to_tree(tmscm obj)216 tmscm_to_tree (tmscm obj) {
217   return open_box<tree>(tmscm_to_blackbox (obj));
218 }
219 
220 tmscm
treeP(tmscm t)221 treeP (tmscm t) {
222   bool b= tmscm_is_blackbox (t) &&
223           (type_box (tmscm_to_blackbox(t)) == type_helper<tree>::id);
224   return bool_to_tmscm (b);
225 }
226 
227 tree
coerce_string_tree(string s)228 coerce_string_tree (string s) {
229   return s;
230 }
231 
232 string
coerce_tree_string(tree t)233 coerce_tree_string (tree t) {
234   return as_string (t);
235 }
236 
237 tree
tree_ref(tree t,int i)238 tree_ref (tree t, int i) {
239   return t[i];
240 }
241 
242 tree
tree_set(tree t,int i,tree u)243 tree_set (tree t, int i, tree u) {
244   t[i]= u;
245   return u;
246 }
247 
248 tree
tree_range(tree t,int i,int j)249 tree_range (tree t, int i, int j) {
250   return t(i,j);
251 }
252 
253 tree
tree_append(tree t1,tree t2)254 tree_append (tree t1, tree t2) {
255   return t1 * t2;
256 }
257 
258 bool
tree_active(tree t)259 tree_active (tree t) {
260   path ip= obtain_ip (t);
261   return is_nil (ip) || last_item (ip) != DETACHED;
262 }
263 
264 tree
tree_child_insert(tree t,int pos,tree x)265 tree_child_insert (tree t, int pos, tree x) {
266   //cout << "t= " << t << "\n";
267   //cout << "x= " << x << "\n";
268   int i, n= N(t);
269   tree r (t, n+1);
270   for (i=0; i<pos; i++) r[i]= t[i];
271   r[pos]= x;
272   for (i=pos; i<n; i++) r[i+1]= t[i];
273   return r;
274 }
275 
276 /******************************************************************************
277 * Document modification routines
278 ******************************************************************************/
279 
280 extern tree the_et;
281 
282 tree
tree_assign(tree r,tree t)283 tree_assign (tree r, tree t) {
284   path ip= copy (obtain_ip (r));
285   if (ip_attached (ip)) {
286     assign (reverse (ip), copy (t));
287     return subtree (the_et, reverse (ip));
288   }
289   else {
290     assign (r, copy (t));
291     return r;
292   }
293 }
294 
295 tree
tree_insert(tree r,int pos,tree t)296 tree_insert (tree r, int pos, tree t) {
297   path ip= copy (obtain_ip (r));
298   if (ip_attached (ip)) {
299     insert (reverse (path (pos, ip)), copy (t));
300     return subtree (the_et, reverse (ip));
301   }
302   else {
303     insert (r, pos, copy (t));
304     return r;
305   }
306 }
307 
308 tree
tree_remove(tree r,int pos,int nr)309 tree_remove (tree r, int pos, int nr) {
310   path ip= copy (obtain_ip (r));
311   if (ip_attached (ip)) {
312     remove (reverse (path (pos, ip)), nr);
313     return subtree (the_et, reverse (ip));
314   }
315   else {
316     remove (r, pos, nr);
317     return r;
318   }
319 }
320 
321 tree
tree_split(tree r,int pos,int at)322 tree_split (tree r, int pos, int at) {
323   path ip= copy (obtain_ip (r));
324   if (ip_attached (ip)) {
325     split (reverse (path (at, pos, ip)));
326     return subtree (the_et, reverse (ip));
327   }
328   else {
329     split (r, pos, at);
330     return r;
331   }
332 }
333 
334 tree
tree_join(tree r,int pos)335 tree_join (tree r, int pos) {
336   path ip= copy (obtain_ip (r));
337   if (ip_attached (ip)) {
338     join (reverse (path (pos, ip)));
339     return subtree (the_et, reverse (ip));
340   }
341   else {
342     join (r, pos);
343     return r;
344   }
345 }
346 
347 tree
tree_assign_node(tree r,tree_label op)348 tree_assign_node (tree r, tree_label op) {
349   path ip= copy (obtain_ip (r));
350   if (ip_attached (ip)) {
351     assign_node (reverse (ip), op);
352     return subtree (the_et, reverse (ip));
353   }
354   else {
355     assign_node (r, op);
356     return r;
357   }
358 }
359 
360 tree
tree_insert_node(tree r,int pos,tree t)361 tree_insert_node (tree r, int pos, tree t) {
362   path ip= copy (obtain_ip (r));
363   if (ip_attached (ip)) {
364     insert_node (reverse (path (pos, ip)), copy (t));
365     return subtree (the_et, reverse (ip));
366   }
367   else {
368     insert_node (r, pos, copy (t));
369     return r;
370   }
371 }
372 
373 tree
tree_remove_node(tree r,int pos)374 tree_remove_node (tree r, int pos) {
375   path ip= copy (obtain_ip (r));
376   if (ip_attached (ip)) {
377     remove_node (reverse (path (pos, ip)));
378     return subtree (the_et, reverse (ip));
379   }
380   else {
381     remove_node (r, pos);
382     return r;
383   }
384 }
385 
386 /******************************************************************************
387 * Scheme trees
388 ******************************************************************************/
389 
390 #define TMSCM_ASSERT_SCHEME_TREE(p,arg,rout)
391 
392 tmscm
scheme_tree_to_tmscm(scheme_tree t)393 scheme_tree_to_tmscm (scheme_tree t) {
394   if (is_atomic (t)) {
395     string s= t->label;
396     if (s == "#t") return tmscm_true ();
397     if (s == "#f") return tmscm_false ();
398     if (is_int (s)) return int_to_tmscm (as_int (s));
399     if (is_quoted (s))
400       return string_to_tmscm (scm_unquote (s));
401     //if ((N(s)>=2) && (s[0]=='\42') && (s[N(s)-1]=='\42'))
402     //return string_to_tmscm (s (1, N(s)-1));
403     if (N(s) >= 1 && s[0] == '\'') return symbol_to_tmscm (s (1, N(s)));
404     return symbol_to_tmscm (s);
405   }
406   else {
407     int i;
408     tmscm p= tmscm_null ();
409     for (i=N(t)-1; i>=0; i--)
410       p= tmscm_cons (scheme_tree_to_tmscm (t[i]), p);
411     return p;
412   }
413 }
414 
415 scheme_tree
tmscm_to_scheme_tree(tmscm p)416 tmscm_to_scheme_tree (tmscm p) {
417   if (tmscm_is_list (p)) {
418     tree t (TUPLE);
419     while (!tmscm_is_null (p)) {
420       t << tmscm_to_scheme_tree (tmscm_car (p));
421       p= tmscm_cdr (p);
422     }
423     return t;
424   }
425   if (tmscm_is_symbol (p)) return tmscm_to_symbol (p);
426   if (tmscm_is_string (p)) return scm_quote (tmscm_to_string (p));
427   //if (tmscm_is_string (p)) return "\"" * tmscm_to_string (p) * "\"";
428   if (tmscm_is_int (p)) return as_string ((int) tmscm_to_int (p));
429   if (tmscm_is_bool (p)) return (tmscm_to_bool (p)? string ("#t"): string ("#f"));
430   if (tmscm_is_tree (p)) return tree_to_scheme_tree (tmscm_to_tree (p));
431   return "?";
432 }
433 
434 /******************************************************************************
435 * Content
436 ******************************************************************************/
437 
438 bool
tmscm_is_content(tmscm p)439 tmscm_is_content (tmscm p) {
440   if (tmscm_is_string (p) || tmscm_is_tree (p)) return true;
441   else if (!tmscm_is_pair (p) || !tmscm_is_symbol (tmscm_car (p))) return false;
442   else {
443     for (p= tmscm_cdr (p); !tmscm_is_null (p); p= tmscm_cdr (p))
444       if (!tmscm_is_content (tmscm_car (p))) return false;
445     return true;
446   }
447 }
448 
449 #define content tree
450 #define TMSCM_ASSERT_CONTENT(p,arg,rout) \
451    TMSCM_ASSERT (tmscm_is_content (p), p, arg, rout)
452 #define content_to_tmscm tree_to_tmscm
453 
454 tree
tmscm_to_content(tmscm p)455 tmscm_to_content (tmscm p) {
456   if (tmscm_is_string (p)) return tmscm_to_string (p);
457   if (tmscm_is_tree (p)) return tmscm_to_tree (p);
458   if (tmscm_is_pair (p)) {
459     if (!tmscm_is_symbol (tmscm_car (p))) return "?";
460     tree t (make_tree_label (tmscm_to_symbol (tmscm_car (p))));
461     p= tmscm_cdr (p);
462     while (!tmscm_is_null (p)) {
463       t << tmscm_to_content (tmscm_car (p));
464       p= tmscm_cdr (p);
465     }
466     return t;
467   }
468   return "?";
469 }
470 
471 tmscm
contentP(tmscm t)472 contentP (tmscm t) {
473   bool b= tmscm_is_content (t);
474   return bool_to_tmscm (b);
475 }
476 
477 /******************************************************************************
478 * Paths
479 ******************************************************************************/
480 
481 bool
tmscm_is_path(tmscm p)482 tmscm_is_path (tmscm p) {
483   if (tmscm_is_null (p)) return true;
484   else return tmscm_is_int (tmscm_car (p)) && tmscm_is_path (tmscm_cdr (p));
485 }
486 
487 #define TMSCM_ASSERT_PATH(p,arg,rout) \
488 TMSCM_ASSERT (tmscm_is_path (p), p, arg, rout)
489 
490 tmscm
path_to_tmscm(path p)491 path_to_tmscm (path p) {
492   if (is_nil (p)) return tmscm_null ();
493   else return tmscm_cons (int_to_tmscm (p->item), path_to_tmscm (p->next));
494 }
495 
496 path
tmscm_to_path(tmscm p)497 tmscm_to_path (tmscm p) {
498   if (tmscm_is_null (p)) return path ();
499   else return path ((int) tmscm_to_int (tmscm_car (p)),
500                           tmscm_to_path (tmscm_cdr (p)));
501 }
502 
503 
504 /******************************************************************************
505 * Observers
506 ******************************************************************************/
507 
508 #define TMSCM_ASSERT_OBSERVER(o,arg,rout) \
509 TMSCM_ASSERT (tmscm_is_observer (o), o, arg, rout)
510 
511 
512 bool
tmscm_is_observer(tmscm o)513 tmscm_is_observer (tmscm o) {
514   return (tmscm_is_blackbox (o) &&
515          (type_box (tmscm_to_blackbox(o)) == type_helper<observer>::id));
516 }
517 
518 tmscm
observer_to_tmscm(observer o)519 observer_to_tmscm (observer o) {
520   return blackbox_to_tmscm (close_box<observer> (o));
521 }
522 
523 static observer
tmscm_to_observer(tmscm obj)524 tmscm_to_observer (tmscm obj) {
525   return open_box<observer>(tmscm_to_blackbox (obj));
526 }
527 
528 tmscm
observerP(tmscm t)529 observerP (tmscm t) {
530   bool b= tmscm_is_blackbox (t) &&
531   (type_box (tmscm_to_blackbox(t)) == type_helper<observer>::id);
532   return bool_to_tmscm (b);
533 }
534 
535 
536 /******************************************************************************
537 * Widgets
538 ******************************************************************************/
539 
540 #define TMSCM_ASSERT_WIDGET(o,arg,rout) \
541 TMSCM_ASSERT (tmscm_is_widget (o), o, arg, rout)
542 
543 bool
tmscm_is_widget(tmscm u)544 tmscm_is_widget (tmscm u) {
545   return (tmscm_is_blackbox (u) &&
546          (type_box (tmscm_to_blackbox(u)) == type_helper<widget>::id));
547 }
548 
549 
550 static tmscm
widget_to_tmscm(widget o)551 widget_to_tmscm (widget o) {
552   return blackbox_to_tmscm (close_box<widget> (o));
553 }
554 
555 widget
tmscm_to_widget(tmscm o)556 tmscm_to_widget (tmscm o) {
557   return open_box<widget> (tmscm_to_blackbox (o));
558 }
559 
560 /******************************************************************************
561 * Commands
562 ******************************************************************************/
563 
564 #define TMSCM_ASSERT_COMMAND(o,arg,rout) \
565 TMSCM_ASSERT (tmscm_is_command (o), o, arg, rout)
566 
567 bool
tmscm_is_command(tmscm u)568 tmscm_is_command (tmscm u) {
569   return (tmscm_is_blackbox (u) &&
570       (type_box (tmscm_to_blackbox(u)) == type_helper<command>::id));
571 }
572 
573 static tmscm
command_to_tmscm(command o)574 command_to_tmscm (command o) {
575   return blackbox_to_tmscm (close_box<command> (o));
576 }
577 
578 static command
tmscm_to_command(tmscm o)579 tmscm_to_command (tmscm o) {
580   return open_box<command> (tmscm_to_blackbox (o));
581 }
582 
583 
584 /******************************************************************************
585 *  Widget Factory
586 ******************************************************************************/
587 
588 typedef promise<widget> promise_widget;
589 
590 #define TMSCM_ASSERT_PROMISE_WIDGET(o,arg,rout) \
591 TMSCM_ASSERT (tmscm_is_promise_widget (o), o, arg, rout)
592 
593 bool
tmscm_is_promise_widget(tmscm u)594 tmscm_is_promise_widget (tmscm u) {
595   return (tmscm_is_blackbox (u) &&
596          (type_box (tmscm_to_blackbox(u)) == type_helper<promise_widget>::id));
597 }
598 
599 static tmscm
promise_widget_to_tmscm(promise_widget o)600 promise_widget_to_tmscm (promise_widget o) {
601   return blackbox_to_tmscm (close_box<promise_widget> (o));
602 }
603 
604 static promise_widget
tmscm_to_promise_widget(tmscm o)605 tmscm_to_promise_widget (tmscm o) {
606   return open_box<promise_widget> (tmscm_to_blackbox (o));
607 }
608 
609 /******************************************************************************
610 * Urls
611 ******************************************************************************/
612 
613 bool
tmscm_is_url(tmscm u)614 tmscm_is_url (tmscm u) {
615   return (tmscm_is_blackbox (u)
616               && (type_box (tmscm_to_blackbox(u)) == type_helper<url>::id))
617          || (tmscm_is_string(u));
618 }
619 
620 tmscm
url_to_tmscm(url u)621 url_to_tmscm (url u) {
622   return blackbox_to_tmscm (close_box<url> (u));
623 }
624 
625 url
tmscm_to_url(tmscm obj)626 tmscm_to_url (tmscm obj) {
627   if (tmscm_is_string (obj))
628 #ifdef __MINGW32__
629     return url_system (tmscm_to_string (obj));
630 #else
631   return tmscm_to_string (obj);
632 #endif
633   return open_box<url> (tmscm_to_blackbox (obj));
634 }
635 
636 tmscm
urlP(tmscm t)637 urlP (tmscm t) {
638   bool b= tmscm_is_url (t);
639   return bool_to_tmscm (b);
640 }
641 
url_concat(url u1,url u2)642 url url_concat (url u1, url u2) { return u1 * u2; }
url_or(url u1,url u2)643 url url_or (url u1, url u2) { return u1 | u2; }
string_save(string s,url u)644 void string_save (string s, url u) { (void) save_string (u, s); }
string_load(url u)645 string string_load (url u) {
646   string s; (void) load_string (u, s, false); return s; }
string_append_to_file(string s,url u)647 void string_append_to_file (string s, url u) { (void) append_string (u, s); }
url_ref(url u,int i)648 url url_ref (url u, int i) { return u[i]; }
649 
650 /******************************************************************************
651 * Modification
652 ******************************************************************************/
653 
654 bool
tmscm_is_modification(tmscm m)655 tmscm_is_modification (tmscm m) {
656   return (tmscm_is_blackbox (m) &&
657 	  (type_box (tmscm_to_blackbox(m)) == type_helper<modification>::id))
658     || (tmscm_is_string (m));
659 }
660 
661 tmscm
modification_to_tmscm(modification m)662 modification_to_tmscm (modification m) {
663   return blackbox_to_tmscm (close_box<modification> (m));
664 }
665 
666 modification
tmscm_to_modification(tmscm obj)667 tmscm_to_modification (tmscm obj) {
668   return open_box<modification> (tmscm_to_blackbox (obj));
669 }
670 
671 tmscm
modificationP(tmscm t)672 modificationP (tmscm t) {
673   bool b= tmscm_is_modification (t);
674   return bool_to_tmscm (b);
675 }
676 
677 tree
var_apply(tree & t,modification m)678 var_apply (tree& t, modification m) {
679   apply (t, copy (m));
680   return t;
681 }
682 
683 tree
var_clean_apply(tree & t,modification m)684 var_clean_apply (tree& t, modification m) {
685   return clean_apply (t, copy (m));
686 }
687 
688 /******************************************************************************
689 * Patch
690 ******************************************************************************/
691 
692 bool
tmscm_is_patch(tmscm p)693 tmscm_is_patch (tmscm p) {
694   return (tmscm_is_blackbox (p) &&
695 	  (type_box (tmscm_to_blackbox(p)) == type_helper<patch>::id))
696     || (tmscm_is_string (p));
697 }
698 
699 tmscm
patch_to_tmscm(patch p)700 patch_to_tmscm (patch p) {
701   return blackbox_to_tmscm (close_box<patch> (p));
702 }
703 
704 patch
tmscm_to_patch(tmscm obj)705 tmscm_to_patch (tmscm obj) {
706   return open_box<patch> (tmscm_to_blackbox (obj));
707 }
708 
709 tmscm
patchP(tmscm t)710 patchP (tmscm t) {
711   bool b= tmscm_is_patch (t);
712   return bool_to_tmscm (b);
713 }
714 
715 patch
branch_patch(array<patch> a)716 branch_patch (array<patch> a) {
717   return patch (true, a);
718 }
719 
720 tree
var_clean_apply(tree t,patch p)721 var_clean_apply (tree t, patch p) {
722   return clean_apply (copy (p), t);
723 }
724 
725 tree
var_apply(tree & t,patch p)726 var_apply (tree& t, patch p) {
727   apply (copy (p), t);
728   return t;
729 }
730 
731 /******************************************************************************
732 * Table types
733 ******************************************************************************/
734 
735 typedef hashmap<string,string> table_string_string;
736 
737 static bool
tmscm_is_table_string_string(tmscm p)738 tmscm_is_table_string_string (tmscm p) {
739   if (tmscm_is_null (p)) return true;
740   else if (!tmscm_is_pair (p)) return false;
741   else {
742     tmscm f= tmscm_car (p);
743     return tmscm_is_pair (f) &&
744     tmscm_is_string (tmscm_car (f)) &&
745     tmscm_is_string (tmscm_cdr (f)) &&
746     tmscm_is_table_string_string (tmscm_cdr (p));
747   }
748 }
749 
750 #define TMSCM_ASSERT_TABLE_STRING_STRING(p,arg,rout) \
751 TMSCM_ASSERT (tmscm_is_table_string_string (p), p, arg, rout)
752 
753 tmscm
table_string_string_to_tmscm(hashmap<string,string> t)754 table_string_string_to_tmscm (hashmap<string,string> t) {
755   tmscm p= tmscm_null ();
756   iterator<string> it= iterate (t);
757   while (it->busy ()) {
758     string s= it->next ();
759     tmscm n= tmscm_cons (string_to_tmscm (s), string_to_tmscm (t[s]));
760     p= tmscm_cons (n, p);
761   }
762   return p;
763 }
764 
765 hashmap<string,string>
tmscm_to_table_string_string(tmscm p)766 tmscm_to_table_string_string (tmscm p) {
767   hashmap<string,string> t;
768   while (!tmscm_is_null (p)) {
769     tmscm n= tmscm_car (p);
770     t (tmscm_to_string (tmscm_car (n)))= tmscm_to_string (tmscm_cdr (n));
771     p= tmscm_cdr (p);
772   }
773   return t;
774 }
775 
776 #define tmscm_is_solution tmscm_is_table_string_string
777 #define TMSCM_ASSERT_SOLUTION(p,arg,rout) \
778 TMSCM_ASSERT (tmscm_is_solution(p), p, arg, rout)
779 #define solution_to_tmscm table_string_string_to_tmscm
780 #define tmscm_to_solution tmscm_to_table_string_string
781 
782 /******************************************************************************
783 * Several array types
784 ******************************************************************************/
785 
786 typedef array<int> array_int;
787 typedef array<string> array_string;
788 typedef array<tree> array_tree;
789 typedef array<url> array_url;
790 typedef array<patch> array_patch;
791 typedef array<path> array_path;
792 typedef array<widget> array_widget;
793 typedef array<double> array_double;
794 typedef array<array<double> > array_array_double;
795 typedef array<array<array<double> > > array_array_array_double;
796 
797 static bool
tmscm_is_array_int(tmscm p)798 tmscm_is_array_int (tmscm p) {
799   if (tmscm_is_null (p)) return true;
800   else return tmscm_is_pair (p) &&
801     tmscm_is_int (tmscm_car (p)) &&
802     tmscm_is_array_int (tmscm_cdr (p));
803 }
804 
805 #define TMSCM_ASSERT_ARRAY_INT(p,arg,rout) \
806 TMSCM_ASSERT (tmscm_is_array_int (p), p, arg, rout)
807 
808 /* static */ tmscm
array_int_to_tmscm(array<int> a)809 array_int_to_tmscm (array<int> a) {
810   int i, n= N(a);
811   tmscm p= tmscm_null ();
812   for (i=n-1; i>=0; i--) p= tmscm_cons (int_to_tmscm (a[i]), p);
813   return p;
814 }
815 
816 /* static */ array<int>
tmscm_to_array_int(tmscm p)817 tmscm_to_array_int (tmscm p) {
818   array<int> a;
819   while (!tmscm_is_null (p)) {
820     a << ((int) tmscm_to_int (tmscm_car (p)));
821     p= tmscm_cdr (p);
822   }
823   return a;
824 }
825 
826 static bool
tmscm_is_array_string(tmscm p)827 tmscm_is_array_string (tmscm p) {
828   if (tmscm_is_null (p)) return true;
829   else return tmscm_is_pair (p) &&
830     tmscm_is_string (tmscm_car (p)) &&
831     tmscm_is_array_string (tmscm_cdr (p));
832 }
833 
834 
835 static bool
tmscm_is_array_double(tmscm p)836 tmscm_is_array_double (tmscm p) {
837   if (tmscm_is_null (p)) return true;
838   else return tmscm_is_pair (p) &&
839     tmscm_is_double (tmscm_car (p)) &&
840     tmscm_is_array_double (tmscm_cdr (p));
841 }
842 
843 #define TMSCM_ASSERT_ARRAY_DOUBLE(p,arg,rout) \
844 TMSCM_ASSERT (tmscm_is_array_double (p), p, arg, rout)
845 
846 /* static */ tmscm
array_double_to_tmscm(array<double> a)847 array_double_to_tmscm (array<double> a) {
848   int i, n= N(a);
849   tmscm p= tmscm_null();
850   for (i=n-1; i>=0; i--) p= tmscm_cons (double_to_tmscm (a[i]), p);
851   return p;
852 }
853 
854 /* static */ array<double>
tmscm_to_array_double(tmscm p)855 tmscm_to_array_double (tmscm p) {
856   array<double> a;
857   while (!tmscm_is_null (p)) {
858     a << ((double) tmscm_to_double (tmscm_car (p)));
859     p= tmscm_cdr (p);
860   }
861   return a;
862 }
863 
864 static bool
tmscm_is_array_array_double(tmscm p)865 tmscm_is_array_array_double (tmscm p) {
866   if (tmscm_is_null (p)) return true;
867   else return tmscm_is_pair (p) &&
868     tmscm_is_array_double (tmscm_car (p)) &&
869     tmscm_is_array_array_double (tmscm_cdr (p));
870 }
871 
872 #define TMSCM_ASSERT_ARRAY_ARRAY_DOUBLE(p,arg,rout) \
873 TMSCM_ASSERT (tmscm_is_array_array_double (p), p, arg, rout)
874 
875 /* static */ tmscm
array_array_double_to_tmscm(array<array_double> a)876 array_array_double_to_tmscm (array<array_double> a) {
877   int i, n= N(a);
878   tmscm p= tmscm_null ();
879   for (i=n-1; i>=0; i--) p= tmscm_cons (array_double_to_tmscm (a[i]), p);
880   return p;
881 }
882 
883 /* static */ array<array_double>
tmscm_to_array_array_double(tmscm p)884 tmscm_to_array_array_double (tmscm p) {
885   array<array_double> a;
886   while (!tmscm_is_null (p)) {
887     a << ((array_double) tmscm_to_array_double (tmscm_car (p)));
888     p= tmscm_cdr (p);
889   }
890   return a;
891 }
892 
893 static bool
tmscm_is_array_array_array_double(tmscm p)894 tmscm_is_array_array_array_double (tmscm p) {
895   if (tmscm_is_null (p)) return true;
896   else return tmscm_is_pair (p) &&
897     tmscm_is_array_array_double (tmscm_car (p)) &&
898     tmscm_is_array_array_array_double (tmscm_cdr (p));
899 }
900 
901 #define TMSCM_ASSERT_ARRAY_ARRAY_ARRAY_DOUBLE(p,arg,rout) \
902 TMSCM_ASSERT (tmscm_is_array_array_array_double (p), p, arg, rout)
903 
904 /* static */ tmscm
array_array_array_double_to_tmscm(array<array_array_double> a)905 array_array_array_double_to_tmscm (array<array_array_double> a) {
906   int i, n= N(a);
907   tmscm p= tmscm_null ();
908   for (i=n-1; i>=0; i--) p= tmscm_cons (array_array_double_to_tmscm (a[i]), p);
909   return p;
910 }
911 
912 /* static */ array<array_array_double>
tmscm_to_array_array_array_double(tmscm p)913 tmscm_to_array_array_array_double (tmscm p) {
914   array<array_array_double> a;
915   while (!tmscm_is_null (p)) {
916     a << ((array_array_double) tmscm_to_array_array_double (tmscm_car (p)));
917     p= tmscm_cdr (p);
918   }
919   return a;
920 }
921 
922 void register_glyph (string s, array_array_array_double gl);
923 string recognize_glyph (array_array_array_double gl);
924 
925 
926 
927 #define TMSCM_ASSERT_ARRAY_STRING(p,arg,rout) \
928 TMSCM_ASSERT (tmscm_is_array_string (p), p, arg, rout)
929 
930 /* static */ tmscm
array_string_to_tmscm(array<string> a)931 array_string_to_tmscm (array<string> a) {
932   int i, n= N(a);
933   tmscm p= tmscm_null ();
934   for (i=n-1; i>=0; i--) p= tmscm_cons (string_to_tmscm (a[i]), p);
935   return p;
936 }
937 
938 /* static */ array<string>
tmscm_to_array_string(tmscm p)939 tmscm_to_array_string (tmscm p) {
940   array<string> a;
941   while (!tmscm_is_null (p)) {
942     a << tmscm_to_string (tmscm_car (p));
943     p= tmscm_cdr (p);
944   }
945   return a;
946 }
947 
948 static bool
tmscm_is_array_tree(tmscm p)949 tmscm_is_array_tree (tmscm p) {
950   if (tmscm_is_null (p)) return true;
951   else return tmscm_is_pair (p) &&
952     tmscm_is_tree (tmscm_car (p)) &&
953     tmscm_is_array_tree (tmscm_cdr (p));
954 }
955 
956 #define TMSCM_ASSERT_ARRAY_TREE(p,arg,rout) \
957 TMSCM_ASSERT (tmscm_is_array_tree (p), p, arg, rout)
958 
959 /* static */ tmscm
array_tree_to_tmscm(array<tree> a)960 array_tree_to_tmscm (array<tree> a) {
961   int i, n= N(a);
962   tmscm p= tmscm_null ();
963   for (i=n-1; i>=0; i--) p= tmscm_cons (tree_to_tmscm (a[i]), p);
964   return p;
965 }
966 
967 /* static */ array<tree>
tmscm_to_array_tree(tmscm p)968 tmscm_to_array_tree (tmscm p) {
969   array<tree> a;
970   while (!tmscm_is_null (p)) {
971     a << tmscm_to_tree (tmscm_car (p));
972     p= tmscm_cdr (p);
973   }
974   return a;
975 }
976 
977 static bool
tmscm_is_array_widget(tmscm p)978 tmscm_is_array_widget (tmscm p) {
979   if (tmscm_is_null (p)) return true;
980   else return tmscm_is_pair (p) &&
981     tmscm_is_widget (tmscm_car (p)) &&
982     tmscm_is_array_widget (tmscm_cdr (p));
983 }
984 
985 #define TMSCM_ASSERT_ARRAY_WIDGET(p,arg,rout) \
986 TMSCM_ASSERT (tmscm_is_array_widget (p), p, arg, rout)
987 
988 /* static */ tmscm
array_widget_to_tmscm(array<widget> a)989 array_widget_to_tmscm (array<widget> a) {
990   int i, n= N(a);
991   tmscm p= tmscm_null ();
992   for (i=n-1; i>=0; i--) p= tmscm_cons (widget_to_tmscm (a[i]), p);
993   return p;
994 }
995 
996 /* static */ array<widget>
tmscm_to_array_widget(tmscm p)997 tmscm_to_array_widget (tmscm p) {
998   array<widget> a;
999   while (!tmscm_is_null (p)) {
1000     a << tmscm_to_widget (tmscm_car (p));
1001     p= tmscm_cdr (p);
1002   }
1003   return a;
1004 }
1005 
1006 static bool
tmscm_is_array_url(tmscm p)1007 tmscm_is_array_url (tmscm p) {
1008   if (tmscm_is_null (p)) return true;
1009   else return tmscm_is_pair (p) &&
1010     tmscm_is_url (tmscm_car (p)) &&
1011     tmscm_is_array_url (tmscm_cdr (p));
1012 }
1013 
1014 
1015 #define TMSCM_ASSERT_ARRAY_URL(p,arg,rout) \
1016 TMSCM_ASSERT (tmscm_is_array_url (p), p, arg, rout)
1017 
1018 /* static */ tmscm
array_url_to_tmscm(array<url> a)1019 array_url_to_tmscm (array<url> a) {
1020   int i, n= N(a);
1021   tmscm p= tmscm_null ();
1022   for (i=n-1; i>=0; i--) p= tmscm_cons (url_to_tmscm (a[i]), p);
1023   return p;
1024 }
1025 
1026 /* static */ array<url>
tmscm_to_array_url(tmscm p)1027 tmscm_to_array_url (tmscm p) {
1028   array<url> a;
1029   while (!tmscm_is_null (p)) {
1030     a << tmscm_to_url (tmscm_car (p));
1031     p= tmscm_cdr (p);
1032   }
1033   return a;
1034 }
1035 
1036 static bool
tmscm_is_array_patch(tmscm p)1037 tmscm_is_array_patch (tmscm p) {
1038   if (tmscm_is_null (p)) return true;
1039   else return tmscm_is_pair (p) &&
1040     tmscm_is_patch (tmscm_car (p)) &&
1041     tmscm_is_array_patch (tmscm_cdr (p));
1042 }
1043 
1044 
1045 #define TMSCM_ASSERT_ARRAY_PATCH(p,arg,rout) \
1046 TMSCM_ASSERT (tmscm_is_array_patch (p), p, arg, rout)
1047 
1048 /* static */ tmscm
array_patch_to_tmscm(array<patch> a)1049 array_patch_to_tmscm (array<patch> a) {
1050   int i, n= N(a);
1051   tmscm p= tmscm_null ();
1052   for (i=n-1; i>=0; i--) p= tmscm_cons (patch_to_tmscm (a[i]), p);
1053   return p;
1054 }
1055 
1056 /* static */ array<patch>
tmscm_to_array_patch(tmscm p)1057 tmscm_to_array_patch (tmscm p) {
1058   array<patch> a;
1059   while (!tmscm_is_null (p)) {
1060     a << tmscm_to_patch (tmscm_car (p));
1061     p= tmscm_cdr (p);
1062   }
1063   return a;
1064 }
1065 
1066 static bool
tmscm_is_array_path(tmscm p)1067 tmscm_is_array_path (tmscm p) {
1068   if (tmscm_is_null (p)) return true;
1069   else return tmscm_is_pair (p) &&
1070     tmscm_is_path (tmscm_car (p)) &&
1071     tmscm_is_array_path (tmscm_cdr (p));
1072 }
1073 
1074 #define TMSCM_ASSERT_ARRAY_PATH(p,arg,rout) \
1075 TMSCM_ASSERT (tmscm_is_array_path (p), p, arg, rout)
1076 
1077 /* static */ tmscm
array_path_to_tmscm(array<path> a)1078 array_path_to_tmscm (array<path> a) {
1079   int i, n= N(a);
1080   tmscm p= tmscm_null ();
1081   for (i=n-1; i>=0; i--) p= tmscm_cons (path_to_tmscm (a[i]), p);
1082   return p;
1083 }
1084 
1085 /* static */ array<path>
tmscm_to_array_path(tmscm p)1086 tmscm_to_array_path (tmscm p) {
1087   array<path> a;
1088   while (!tmscm_is_null (p)) {
1089     a << tmscm_to_path (tmscm_car (p));
1090     p= tmscm_cdr (p);
1091   }
1092   return a;
1093 }
1094 
1095 /******************************************************************************
1096 * List types
1097 ******************************************************************************/
1098 
1099 typedef list<string> list_string;
1100 
1101 bool
tmscm_is_list_string(tmscm p)1102 tmscm_is_list_string (tmscm p) {
1103   if (tmscm_is_null (p)) return true;
1104   else return tmscm_is_pair (p) &&
1105     tmscm_is_string (tmscm_car (p)) &&
1106     tmscm_is_list_string (tmscm_cdr (p));
1107 }
1108 
1109 #define TMSCM_ASSERT_LIST_STRING(p,arg,rout) \
1110 TMSCM_ASSERT (tmscm_is_list_string (p), p, arg, rout)
1111 
1112 tmscm
list_string_to_tmscm(list_string l)1113 list_string_to_tmscm (list_string l) {
1114   if (is_nil (l)) return tmscm_null ();
1115   return tmscm_cons (string_to_tmscm (l->item),
1116            list_string_to_tmscm (l->next));
1117 }
1118 
1119 list_string
tmscm_to_list_string(tmscm p)1120 tmscm_to_list_string (tmscm p) {
1121   if (tmscm_is_null (p)) return list_string ();
1122   return list_string (tmscm_to_string (tmscm_car (p)),
1123             tmscm_to_list_string (tmscm_cdr (p)));
1124 }
1125 
1126 typedef list<tree> list_tree;
1127 
1128 bool
tmscm_is_list_tree(tmscm p)1129 tmscm_is_list_tree (tmscm p) {
1130   if (tmscm_is_null (p)) return true;
1131   else return tmscm_is_pair (p) &&
1132     tmscm_is_tree (tmscm_car (p)) &&
1133     tmscm_is_list_tree (tmscm_cdr (p));
1134 }
1135 
1136 #define TMSCM_ASSERT_LIST_TREE(p,arg,rout) \
1137 TMSCM_ASSERT (tmscm_is_list_tree (p), p, arg, rout)
1138 
1139 tmscm
list_tree_to_tmscm(list_tree l)1140 list_tree_to_tmscm (list_tree l) {
1141   if (is_nil (l)) return tmscm_null ();
1142   return tmscm_cons (tree_to_tmscm (l->item),
1143            list_tree_to_tmscm (l->next));
1144 }
1145 
1146 list_tree
tmscm_to_list_tree(tmscm p)1147 tmscm_to_list_tree (tmscm p) {
1148   if (tmscm_is_null (p)) return list_tree ();
1149   return list_tree (tmscm_to_tree (tmscm_car (p)),
1150             tmscm_to_list_tree (tmscm_cdr (p)));
1151 }
1152 
1153 /******************************************************************************
1154 * Gluing
1155 ******************************************************************************/
1156 
1157 #include "server.hpp"
1158 #include "tm_window.hpp"
1159 #include "boot.hpp"
1160 #include "connect.hpp"
1161 #include "convert.hpp"
1162 #include "file.hpp"
1163 #include "image_files.hpp"
1164 #include "web_files.hpp"
1165 #include "sys_utils.hpp"
1166 #include "client_server.hpp"
1167 #include "analyze.hpp"
1168 #include "wencoding.hpp"
1169 #include "base64.hpp"
1170 #include "tree_traverse.hpp"
1171 #include "tree_analyze.hpp"
1172 #include "tree_correct.hpp"
1173 #include "tree_modify.hpp"
1174 #include "tm_frame.hpp"
1175 #include "Concat/concater.hpp"
1176 #include "converter.hpp"
1177 #include "timer.hpp"
1178 #include "Metafont/tex_files.hpp"
1179 #include "Freetype/tt_file.hpp"
1180 #include "LaTeX_Preview/latex_preview.hpp"
1181 #include "Bibtex/bibtex.hpp"
1182 #include "Bibtex/bibtex_functions.hpp"
1183 #include "link.hpp"
1184 #include "dictionary.hpp"
1185 #include "patch.hpp"
1186 #include "packrat.hpp"
1187 #include "new_style.hpp"
1188 #include "persistent.hpp"
1189 
1190 #include "../Glue/glue_basic.cpp"
1191 #include "../Glue/glue_editor.cpp"
1192 #include "../Glue/glue_server.cpp"
1193 
1194 void
initialize_glue()1195 initialize_glue () {
1196   tmscm_install_procedure ("tree?", treeP, 1, 0, 0);
1197   tmscm_install_procedure ("tm?", contentP, 1, 0, 0);
1198   tmscm_install_procedure ("observer?", observerP, 1, 0, 0);
1199   tmscm_install_procedure ("url?", urlP, 1, 0, 0);
1200   tmscm_install_procedure ("modification?", modificationP, 1, 0, 0);
1201   tmscm_install_procedure ("patch?", patchP, 1, 0, 0);
1202   tmscm_install_procedure ("blackbox?", blackboxP, 1, 0, 0);
1203 
1204   initialize_glue_basic ();
1205   initialize_glue_editor ();
1206   initialize_glue_server ();
1207 }
1208