2
/******************************************************************************
3
* MODULE : bridge_with.cpp
4
* DESCRIPTION: Bridge between logical and physical local enviroment changes
5
* COPYRIGHT : (C) 1999 Joris van der Hoeven
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.
11
******************************************************************************/
15
class bridge_with_rep: public bridge_rep {
21
bridge_with_rep (typesetter ttt, tree st, path ip);
24
void notify_assign (path p, tree u);
25
void notify_insert (path p, tree u);
26
void notify_remove (path p, int nr);
27
bool notify_macro (int type, string var, int level, path p, tree u);
28
void notify_change ();
30
void my_exec_until (path p);
31
bool my_typeset_will_be_complete ();
32
void my_typeset (int desired_status);
35
bridge_with_rep::bridge_with_rep (typesetter ttt, tree st, path ip):
36
bridge_rep (ttt, st, ip)
42
bridge_with_rep::initialize () {
44
if (nil(body)) body= make_bridge (ttt, st[last], descend (ip, last));
45
else replace_bridge (body, st[last], descend (ip, last));
49
bridge_with (typesetter ttt, tree st, path ip) {
50
return new bridge_with_rep (ttt, st, ip);
53
/******************************************************************************
55
******************************************************************************/
58
bridge_with_rep::notify_assign (path p, tree u) {
59
// cout << "Assign " << p << ", " << u << " in " << st << "\n";
60
if (nil (p) && (!is_func (u, WITH)))
61
fatal_error ("Nil path", "bridge_with_rep::notify_assign");
67
bool mp_flag= is_multi_paragraph (st);
68
if (p->item == last) {
69
if (atom (p)) body= make_bridge (ttt, u, descend (ip, last));
70
else body->notify_assign (p->next, u);
71
st= substitute (st, p->item, body->st);
74
st= substitute (st, p, u);
75
body->notify_change ();
77
if (mp_flag != is_multi_paragraph (st)) initialize ();
83
bridge_with_rep::notify_insert (path p, tree u) {
84
// cout << "Insert " << p << ", " << u << " in " << st << "\n";
85
if (nil (p)) fatal_error ("Nil path", "bridge_with_rep::notify_insert");
86
if (atom (p) || (p->item != last)) bridge_rep::notify_insert (p, u);
88
bool mp_flag= is_multi_paragraph (st);
89
body->notify_insert (p->next, u);
90
st= substitute (st, last, body->st);
91
if (mp_flag != is_multi_paragraph (st)) initialize ();
97
bridge_with_rep::notify_remove (path p, int nr) {
98
// cout << "Remove " << p << ", " << nr << " in " << st << "\n";
99
if (nil (p)) fatal_error ("Nil path", "bridge_with_rep::notify_remove");
100
if (atom (p) || (p->item != last)) bridge_rep::notify_remove (p, nr);
102
bool mp_flag= is_multi_paragraph (st);
103
body->notify_remove (p->next, nr);
104
st= substitute (st, last, body->st);
105
if (mp_flag != is_multi_paragraph (st)) initialize ();
111
bridge_with_rep::notify_macro (int type, string var, int l, path p, tree u) {
112
bool flag= body->notify_macro (type, var, l, p, u);
113
if (flag) status= CORRUPTED;
118
bridge_with_rep::notify_change () {
120
body->notify_change ();
123
/******************************************************************************
125
******************************************************************************/
128
bridge_with_rep::my_exec_until (path p) {
129
int i, k= last>>1; // is k=0 allowed ?
130
if (((last&1) != 0) || (p->item != last)) return;
131
STACK_NEW_ARRAY(vars,string,k);
132
STACK_NEW_ARRAY(newv,tree,k);
133
for (i=0; i<k; i++) {
134
tree var_t= env->exec (st[i<<1]);
135
if (is_atomic (var_t)) {
136
string var= var_t->label;
138
newv[i]= env->exec (st[(i<<1)+1]);
141
STACK_DELETE_ARRAY(vars);
142
STACK_DELETE_ARRAY(newv);
146
for (i=0; i<k; i++) env->monitored_write_update (vars[i], newv[i]);
147
body->exec_until (p->next);
148
STACK_DELETE_ARRAY(vars);
149
STACK_DELETE_ARRAY(newv);
153
bridge_with_rep::my_typeset_will_be_complete () {
154
if (status != CORRUPTED) return false;
155
return body->my_typeset_will_be_complete ();
159
bridge_with_rep::my_typeset (int desired_status) {
160
int i, k= last>>1; // is k=0 allowed ?
161
// if ((last&1) != 0) return;
163
STACK_NEW_ARRAY(vars,string,k);
164
STACK_NEW_ARRAY(oldv,tree,k);
165
STACK_NEW_ARRAY(newv,tree,k);
166
for (i=0; i<k; i++) {
167
tree var_t= env->exec (st[i<<1]);
168
if (is_atomic (var_t)) {
169
string var= var_t->label;
171
oldv[i]= env->read (var);
172
newv[i]= env->exec (st[(i<<1)+1]);
176
STACK_DELETE_ARRAY(vars);
177
STACK_DELETE_ARRAY(oldv);
178
STACK_DELETE_ARRAY(newv);
184
// for (i=0; i<k; i++) env->monitored_write_update (vars[i], newv[i]);
185
for (i=0; i<k; i++) env->write_update (vars[i], newv[i]);
186
ttt->insert_marker (st, ip);
187
body->typeset (desired_status);
188
for (i=k-1; i>=0; i--) env->write_update (vars[i], oldv[i]);
189
STACK_DELETE_ARRAY(vars);
190
STACK_DELETE_ARRAY(oldv);
191
STACK_DELETE_ARRAY(newv);