1 /*@z18.c:Galley Transfer:Declarations@****************************************/
2 /*                                                                           */
3 /*  THE LOUT DOCUMENT FORMATTING SYSTEM (VERSION 3.39)                       */
4 /*  COPYRIGHT (C) 1991, 2008 Jeffrey H. Kingston                             */
5 /*                                                                           */
6 /*  Jeffrey H. Kingston (jeff@it.usyd.edu.au)                                */
7 /*  School of Information Technologies                                       */
8 /*  The University of Sydney 2006                                            */
9 /*  AUSTRALIA                                                                */
10 /*                                                                           */
11 /*  This program is free software; you can redistribute it and/or modify     */
12 /*  it under the terms of the GNU General Public License as published by     */
13 /*  the Free Software Foundation; either Version 3, or (at your option)      */
14 /*  any later version.                                                       */
15 /*                                                                           */
16 /*  This program is distributed in the hope that it will be useful,          */
17 /*  but WITHOUT ANY WARRANTY; without even the implied warranty of           */
18 /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            */
19 /*  GNU General Public License for more details.                             */
20 /*                                                                           */
21 /*  You should have received a copy of the GNU General Public License        */
22 /*  along with this program; if not, write to the Free Software              */
23 /*  Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307 USA   */
24 /*                                                                           */
25 /*  FILE:         z18.c                                                      */
26 /*  MODULE:       Galley Transfer                                            */
27 /*  EXTERNS:      TransferInit(), TransferBegin(), TransferComponent(),      */
28 /*                TransferEnd(), TransferClose()                             */
29 /*                                                                           */
30 /*****************************************************************************/
31 #include "externs.h"
32 
33 #define	MAX_DEPTH  	30			/* max depth of galleys      */
34 static OBJECT		root_galley;		/* the root galley           */
35 static OBJECT		targets[MAX_DEPTH];	/* currently open \Inputs    */
36 static CONSTRAINT	constraints[MAX_DEPTH];	/* their COLM constraints    */
37 static int		itop;			/* stack top	             */
38 static CONSTRAINT	initial_constraint;	/* initial COLM constraint   */
39        CONTEXT		InitialContext =	/* initial context	     */
40 	 { nilobj, nilobj, nilobj, NULL };
41        STYLE		InitialStyle;		/* initial style             */
42        OBJECT		InitialEnvironment;	/* initial environment	     */
43 
44 #if DEBUG_ON
debug_targets(void)45 static void debug_targets(void)
46 { int i;  OBJECT tmp;
47   for( i = 0;  i <= itop;  i++ )
48   { if( targets[i] == nilobj || Down(targets[i]) == targets[i] )  tmp = nilobj;
49     else Child(tmp, Down(targets[i]));
50     debug3(DGT, D, "  target[%d] %s = %s", i,
51       EchoConstraint(&constraints[i]), EchoObject(tmp));
52   }
53 } /* end debug_targets */
54 #endif
55 
56 
57 /*@::TransferInit()@**********************************************************/
58 /*                                                                           */
59 /*  TransferInit(InitEnv)                                                    */
60 /*                                                                           */
61 /*  Initialise this module.  The initial environment is InitEnv.             */
62 /*                                                                           */
63 /*****************************************************************************/
64 
TransferInit(OBJECT InitEnv)65 void TransferInit(OBJECT InitEnv)
66 { OBJECT dest, x, y, recs, inners, nothing, dest_index, up_hd, why;
67   debug1(DGT, D, "[ TransferInit( %s )", EchoObject(InitEnv));
68   SetConstraint(initial_constraint,
69     MAX_FULL_LENGTH-1, MAX_FULL_LENGTH-1, MAX_FULL_LENGTH-1);
70 
71   /* set initial environment and style */
72   InitialEnvironment = InitEnv;
73   SetGap(line_gap(InitialStyle), FALSE,FALSE,FALSE,FIXED_UNIT,MARK_MODE,18*PT);
74   vadjust(InitialStyle)         = FALSE;
75   hadjust(InitialStyle)         = FALSE;
76   padjust(InitialStyle)         = FALSE;
77   space_style(InitialStyle)     = SPACE_LOUT;
78   SetGap(space_gap(InitialStyle), FALSE,FALSE,TRUE,FIXED_UNIT,EDGE_MODE,1*EM);
79   hyph_style(InitialStyle)      = HYPH_UNDEF;
80   fill_style(InitialStyle)      = FILL_UNDEF;
81   display_style(InitialStyle)   = DISPLAY_UNDEF;
82   small_caps(InitialStyle)      = SMALL_CAPS_OFF;
83   font(InitialStyle)            = 0;			/* i.e. undefined    */
84   colour(InitialStyle)          = 0;			/* i.e. undefined    */
85   underline_colour(InitialStyle)= 0;			/* i.e. undefined    */
86   texture(InitialStyle)         = 1;			/* i.e. "null"       */
87   blanklinescale(InitialStyle)  = SF;			/* i.e. 1.0 (scaled) */
88   outline(InitialStyle)         = FALSE;		/* i.e. not outlined */
89   language(InitialStyle)        = 0;			/* i.e. undefined    */
90   yunit(InitialStyle)           = 0;			/* i.e. zero         */
91   zunit(InitialStyle)           = 0;			/* i.e. zero         */
92   outdent_len(InitialStyle)     = 0;			/* i.e. zero         */
93   smallcaps_len(InitialStyle)   = 0.7 * FR;		/* i.e. 0.7 scale    */
94   nobreakfirst(InitialStyle)	= FALSE;
95   nobreaklast(InitialStyle)	= FALSE;
96   marginkerning(InitialStyle)	= FALSE;
97   baselinemark(InitialStyle)	= FALSE;                /* i.e. not baseline */
98   strut(InitialStyle)		= FALSE;                /* i.e. not strutted */
99   ligatures(InitialStyle)	= TRUE;                 /* i.e. ligatures    */
100   context(InitialStyle) 	= InitialContext;
101 
102   /* construct destination for root galley */
103   New(up_hd, HEAD);
104   FposCopy(fpos(up_hd), *no_fpos);
105   force_gall(up_hd) = FALSE;
106   actual(up_hd) = enclose_obj(up_hd) = limiter(up_hd) = nilobj;
107   ClearHeaders(up_hd);
108   opt_components(up_hd) = opt_constraints(up_hd) = nilobj;
109   gall_dir(up_hd) = ROWM;
110   ready_galls(up_hd) = nilobj;
111   seen_nojoin(up_hd) = must_expand(up_hd) = sized(up_hd) = FALSE;
112   foll_or_prec(up_hd) = GALL_FOLL;
113   whereto(up_hd) = nilobj;
114   New(dest_index, RECEIVING);
115   New(dest, CLOSURE);  actual(dest) = PrintSym;
116   actual(dest_index) = dest;
117   debug2(DGT, D, "TransferInit setting external_ver(%s %s) = TRUE",
118     Image(type(dest)), SymName(actual(dest)));
119   external_ver(dest) = TRUE;
120   external_hor(dest) = FALSE;
121   threaded(dest) = FALSE;
122   blocked(dest_index) = FALSE;
123   Link(up_hd, dest_index);
124 
125   /* construct root galley */
126   New(root_galley, HEAD);
127   FposCopy(fpos(root_galley), *no_fpos);
128   force_gall(root_galley) = FALSE;
129   actual(root_galley) = nilobj;
130   enclose_obj(root_galley) = limiter(root_galley) = nilobj;
131   ClearHeaders(root_galley);
132   opt_components(root_galley) = opt_constraints(root_galley) = nilobj;
133   gall_dir(root_galley) = ROWM;
134   ready_galls(root_galley) = nilobj;
135   must_expand(root_galley) = sized(root_galley) =FALSE;
136   foll_or_prec(root_galley) = GALL_FOLL;
137   whereto(root_galley) = nilobj;
138   seen_nojoin(root_galley) = FALSE;
139   New(x, CLOSURE);  actual(x) = InputSym;
140   Link(root_galley, x);
141   SizeGalley(root_galley, InitEnv, TRUE, FALSE, FALSE, FALSE, &InitialStyle,
142     &initial_constraint, nilobj, &nothing, &recs, &inners, nilobj);
143   debug1(DGA, D, "  TransferInit inners: %s", DebugInnersNames(inners));
144   assert( recs   == nilobj , "TransferInit: recs   != nilobj!" );
145   assert( inners == nilobj , "TransferInit: inners != nilobj!" );
146   Link(dest_index, root_galley);
147 
148   /* initialise target and constraint stacks */
149   Child(y, Down(root_galley));
150   assert( type(y) == RECEPTIVE && type(actual(y)) == CLOSURE &&
151 	actual(actual(y)) == InputSym, "TransferInit: initial galley!" );
152   assert( external_ver(actual(y)), "TransferInit: input sym not external!" );
153   blocked(y) = TRUE;
154   itop = 0;
155   New(targets[itop], ACAT);
156   Link(targets[itop], y);
157   Constrained(actual(y), &constraints[itop], COLM, &why);
158   debug2(DSC, DD, "Constrained( %s, COLM ) = %s",
159 	EchoObject(y), EchoConstraint(&constraints[itop]));
160 
161   debug0(DGT, D, "] TransferInit returning.");
162   ifdebug(DGT, DD, debug_targets());
163 } /* end TransferInit */
164 
165 
166 /*@::TransferBegin()@*********************************************************/
167 /*                                                                           */
168 /*  OBJECT TransferBegin(x)                                                  */
169 /*                                                                           */
170 /*  Commence the transfer of a new galley whose header is invocation x.      */
171 /*                                                                           */
172 /*****************************************************************************/
173 
TransferBegin(OBJECT x)174 OBJECT TransferBegin(OBJECT x)
175 { OBJECT xsym, index, y, link, env, new_env, hold_env, res = nilobj;
176   OBJECT hd, target, why;
177   CONSTRAINT c;
178   debug1(DGT, D, "[ [ TransferBegin( %s )", EchoObject(x));
179   ifdebug(DGT, DD, debug_targets());
180   assert( type(x) == CLOSURE, "TransferBegin: non-CLOSURE!" );
181 
182   /* add an automatically generated @Tag parameter to x if required */
183   if( has_tag(actual(x)) )  CrossAddTag(x);
184 
185   /* construct new (inner) env chain */
186   if( Down(targets[itop]) == targets[itop] )
187     Error(18, 1, "cannot attach galley %s", FATAL,&fpos(x),SymName(actual(x)));
188   Child(target, Down(targets[itop]));
189   xsym = actual(x);
190   env = GetEnv(actual(target));
191   debug1(DGT, DD, "  current env chain: %s", EchoObject(env));
192   if( has_body(xsym) )
193   {
194     /* prepare a copy of x for inclusion in environment */
195     y = CopyObject(x, no_fpos);
196 
197     /* attach its environment */
198     AttachEnv(env, y);
199 
200     /* now the new environment is y catenated with the old one */
201     debug0(DCR, DD, "calling SetEnv from TransferBegin (a)");
202     new_env = SetEnv(y, nilobj);
203   }
204   else new_env = env;
205   New(hold_env, ACAT);  Link(hold_env, new_env);
206   debug1(DGT, DD, "  new env chain: %s", EchoObject(new_env));
207 
208   /* convert x into an unsized galley called hd */
209   New(index, UNATTACHED);
210   actual(index) = nilobj;
211   non_blocking(index) = TRUE;
212   blocked(index) = FALSE;
213   pinpoint(index) = nilobj;
214   New(hd, HEAD);
215   FposCopy(fpos(hd), fpos(x));
216   actual(hd) = xsym;
217   limiter(hd) = opt_components(hd) = opt_constraints(hd) = nilobj;
218   gall_dir(hd) = ROWM;
219   ready_galls(hd) = nilobj;
220   must_expand(hd) = TRUE;
221   sized(hd) = FALSE;
222   seen_nojoin(hd) = FALSE;
223   Link(index, hd);
224   Link(hd, x);
225   AttachEnv(env, x);
226   SetTarget(hd);
227   enclose_obj(hd) = (has_enclose(actual(hd)) ? BuildEnclose(hd) : nilobj);
228   ClearHeaders(hd);
229 
230   /* search for destination for hd and release it */
231   Link(Up(target), index);
232   debug0(DGF,D, "");
233   debug1(DGF,D, "  calling FlushGalley(%s) from TransferBegin, root_galley =",
234     SymName(actual(hd)));
235   ifdebug(DGF, D, DebugGalley(root_galley, nilobj, 4));
236   if( whereto(hd) == nilobj || !uses_extern_target(whereto(hd)) ) /* &&& */
237     FlushGalley(hd);
238 
239   /* if failed to flush, undo everything and exit */
240   Parent(index, Up(hd));
241   if( type(index) == UNATTACHED && !sized(hd) )
242   { DeleteNode(index);
243     DisposeObject(hold_env);
244     if( LastDown(x) != x )
245     { Child(env, LastDown(x));
246       if( type(env) == ENV )  DisposeChild(LastDown(x));
247     }
248     debug1(DGT,D, "] TransferBegin returning failed, x: %s", EchoObject(x));
249     return x;
250   }
251 
252   if( has_rpar(actual(hd)) )
253   {
254     /* set up new target to be inner \InputSym, or nilobj if none */
255     if( ++itop >= MAX_DEPTH )
256       Error(18, 2, "galley nested too deeply (max is %d)",
257 	FATAL, &fpos(x), MAX_DEPTH);
258     New(targets[itop], ACAT);  target = nilobj;
259     for( link = Down(hd);  link != hd;  link = NextDown(link) )
260     { Child(y, link);
261       if( type(y) == RECEPTIVE && actual(actual(y)) == InputSym )
262       {
263 	Constrained(actual(y), &constraints[itop], COLM, &why);
264 	if( FitsConstraint(0, 0, constraints[itop]) )
265 	{ Link(targets[itop], y);  target = y;
266 	  debug2(DSC, DD, "Constrained( %s, COLM ) = %s",
267 	    EchoObject(y), EchoConstraint(&constraints[itop]));
268 	  env = DetachEnv(actual(y));
269 	  AttachEnv(new_env, actual(y));
270 	}
271 	else
272 	{ Error(18, 3, "galley %s deleted (insufficient width at target)",
273 	    WARN, &fpos(hd), SymName(actual(hd)));
274 	}
275 	break;
276       }
277     }
278 
279     /* return a token appropriate to the new target */
280     if( target == nilobj || external_ver(actual(target)) )
281       res = NewToken(GSTUB_EXT, no_fpos, 0, 0, precedence(xsym), nilobj);
282     else
283     { Constrained(actual(target), &c, ROWM, &why);
284       if( constrained(c) )
285 	Error(18, 4, "right parameter of %s is vertically constrained",
286 	  FATAL, &fpos(target), SymName(xsym));
287       else res = NewToken(GSTUB_INT, no_fpos, 0, 0, precedence(xsym), nilobj);
288     }
289     debug1(DGT, D, "] TransferBegin returning %s", Image(type(res)));
290   }
291   else
292   {
293     res = NewToken(GSTUB_NONE, no_fpos, 0, 0, precedence(xsym), nilobj);
294     debug1(DGT, D, "] TransferBegin returning %s", Image(type(res)));
295   }
296 
297   DisposeObject(hold_env);
298   ifdebug(DGT, DD, debug_targets());
299   return res;
300 } /* end TransferBegin */
301 
302 /*@::TransferComponent()@*****************************************************/
303 /*                                                                           */
304 /*  TransferComponent(x)                                                     */
305 /*                                                                           */
306 /*  Transfer component x of a galley.                                        */
307 /*                                                                           */
308 /*****************************************************************************/
309 
TransferComponent(OBJECT x)310 void TransferComponent(OBJECT x)
311 { OBJECT y, env, start_search, recs, inners, nothing, hd, dest, dest_index;
312   debug1(DGT, D, "[ TransferComponent( %s )", EchoObject(x));
313   ifdebug(DGT, DD, debug_targets());
314 
315   /* if no dest_index, discard x and exit */
316   if( Down(targets[itop]) == targets[itop] )
317   { DisposeObject(x);
318     debug0(DGT, D, "] TransferComponent returning (no target).");
319     return;
320   }
321   Child(dest_index, Down(targets[itop]));
322   assert( external_ver(actual(dest_index)), "TransferComponent: internal!" );
323 
324   /* make the component into a galley */
325   New(hd, HEAD);
326   FposCopy(fpos(hd), fpos(x));
327   force_gall(hd) = FALSE;
328   ClearHeaders(hd);
329   enclose_obj(hd) = limiter(hd) = nilobj;
330   opt_components(hd) = opt_constraints(hd) = nilobj;
331   gall_dir(hd) = ROWM;
332   actual(hd) = whereto(hd) = ready_galls(hd) = nilobj;
333   must_expand(hd) = sized(hd) = FALSE;
334   seen_nojoin(hd) = FALSE;
335   foll_or_prec(hd) = GALL_FOLL;
336   Link(hd, x);
337   dest = actual(dest_index);
338   env = GetEnv(dest);
339   debug1(DGT, DD, "  current env chain: %s", EchoObject(env));
340   SizeGalley(hd, env, TRUE, threaded(dest), FALSE, TRUE, &save_style(dest),
341 	&constraints[itop], nilobj, &nothing, &recs, &inners, nilobj);
342   debug1(DGA, D, "  TransferComponent inners: %s", DebugInnersNames(inners));
343   if( recs != nilobj )  ExpandRecursives(recs);
344   debug3(DSA, D, "after SizeGalley, hd width is (%s,%s), constraint was %s",
345     EchoLength(back(hd, COLM)), EchoLength(fwd(hd, COLM)),
346     EchoConstraint(&constraints[itop]));
347 
348   /* promote the components, remembering where old spot was */
349   start_search = PrevDown(Up(dest_index));
350   debug1(DSA, D, "  calling AdjustSize from TransferComponent %s",
351     EchoFilePos(&fpos(hd)));
352   ifdebug(DSA, D,
353     Child(y, Down(hd));
354     while( type(y) == VCAT )  Child(y, Down(y));
355     debug2(DSA, D, "  first component is %s at %s",
356       Image(type(y)), EchoFilePos(&fpos(y)));
357     if( NextDown(Down(hd)) != hd && NextDown(NextDown(Down(hd))) != hd )
358     { Child(y, NextDown(NextDown(Down(hd))));
359       debug2(DSA, D, "  second component is %s at %s",
360         Image(type(y)), EchoFilePos(&fpos(y)));
361     }
362   );
363   AdjustSize(dest, back(hd, COLM), fwd(hd, COLM), COLM);
364   debug0(DGS, D, "calling Promote(hd, hd) from TransferComponent");
365   Promote(hd, hd, dest_index, FALSE);
366   DeleteNode(hd);
367 
368   /* flush any widowed galleys attached to \Input */
369   if( Down(dest_index) != dest_index )
370   { OBJECT tinners, index;
371     New(tinners, ACAT);
372     while( Down(dest_index) != dest_index )
373     { Child(y, Down(dest_index));
374       assert( type(y) == HEAD, "TransferComponent: input child!" );
375       if( opt_components(y) != nilobj )
376       { DisposeObject(opt_components(y));
377 	opt_components(y) = nilobj;
378 	debug1(DOG, D, "TransferComponent de-optimizing %s (@Input case)",
379 	  SymName(actual(y)));
380       }
381       DetachGalley(y);
382       Parent(index, Up(y));
383       MoveLink(Up(index), NextDown(start_search), PARENT);
384       Link(tinners, index);
385     }
386     debug0(DGF, D, "  calling FlushInners() from TransferComponent (a)");
387     FlushInners(tinners, nilobj);
388   }
389 
390   /* flush any galleys inside hd */
391   if( inners != nilobj )
392   {
393     debug0(DGF, D, "  calling FlushInners() from TransferComponent (b)");
394     FlushInners(inners, nilobj);
395   }
396 
397   /* flush parent galley, if needed */
398   if( blocked(dest_index) )
399   { blocked(dest_index) = FALSE;
400     Parent(y, Up(dest_index));
401     debug0(DGF, D, "  calling FlushGalley from TransferComponent");
402     FlushGalley(y);
403   }
404 
405   debug0(DGT, D, "] TransferComponent returning.");
406   ifdebug(DGT, DD, debug_targets());
407 } /* end TransferComponent */
408 
409 
410 /*@::TransferEnd()@***********************************************************/
411 /*                                                                           */
412 /*  TransferEnd(x)                                                           */
413 /*                                                                           */
414 /*  End the transfer of a galley.                                            */
415 /*                                                                           */
416 /*****************************************************************************/
417 
TransferEnd(OBJECT x)418 void TransferEnd(OBJECT x)
419 { OBJECT recs, inners, nothing, z, env, dest, hd, dest_index, y, start_search;
420   debug1(DGT, D, "[ TransferEnd( %s )", EchoObject(x));
421   ifdebug(DGT, DD, debug_targets());
422 
423   /* if no dest_index, discard x and exit */
424   if( Down(targets[itop]) == targets[itop] )
425   { DisposeObject(x);  DisposeObject(targets[itop--]);
426     debug0(DGT, D, "] TransferEnd returning: no dest_index");
427     return;
428   }
429   Child(dest_index, Down(targets[itop]));
430 
431   /* make the component into a galley */
432   New(hd, HEAD);  FposCopy(fpos(hd), fpos(x));
433   force_gall(hd) = FALSE;
434   ClearHeaders(hd);
435   enclose_obj(hd) = limiter(hd) = nilobj;
436   opt_components(hd) = opt_constraints(hd) = nilobj;
437   gall_dir(hd) = ROWM;
438   actual(hd) = whereto(hd) = ready_galls(hd) = nilobj;
439   foll_or_prec(hd) = GALL_FOLL;
440   seen_nojoin(hd) = must_expand(hd) = sized(hd) = FALSE;
441   Link(hd, x);  dest = actual(dest_index);  env = GetEnv(dest);
442   debug1(DGT, DD, "  current env chain: %s", EchoObject(env));
443   SizeGalley(hd, env, external_ver(dest), threaded(dest), FALSE, TRUE,
444     &save_style(dest), &constraints[itop], nilobj, &nothing, &recs, &inners,
445     nilobj);
446   debug1(DGA, D, "  TransferEnd inners: %s", DebugInnersNames(inners));
447   if( recs != nilobj )  ExpandRecursives(recs);
448   debug3(DSA, D, "after SizeGalley, hd width is (%s,%s), constraint was %s",
449     EchoLength(back(hd, COLM)), EchoLength(fwd(hd, COLM)),
450     EchoConstraint(&constraints[itop]));
451 
452   /* promote the components, remembering where old spot was */
453   start_search = PrevDown(Up(dest_index));
454   debug0(DSA, D, "calling AdjustSize from TransferEnd (a)");
455   AdjustSize(dest, back(hd, COLM), fwd(hd, COLM), COLM);
456   if( !external_ver(dest) )
457   { Child(z, LastDown(hd));
458     debug0(DSA, D, "calling AdjustSize from TransferEnd (b)");
459     AdjustSize(dest, back(z, ROWM), fwd(z, ROWM), ROWM);
460     Interpose(dest, VCAT, hd, z);
461   }
462   debug0(DGS, D, "calling Promote(hd, hd) from TransferEnd");
463   Promote(hd, hd, dest_index, TRUE);  DeleteNode(hd);
464 
465   /* flush any widowed galleys attached to \Input */
466   if( Down(dest_index) != dest_index )
467   { OBJECT tinners, index;
468     New(tinners, ACAT);
469     while( Down(dest_index) != dest_index )
470     { Child(y, Down(dest_index));
471       assert( type(y) == HEAD, "TransferEnd: input child!" );
472       if( opt_components(y) != nilobj )
473       { DisposeObject(opt_components(y));
474 	opt_components(y) = nilobj;
475 	debug1(DOG, D, "TransferEnd de-optimizing %s (@Input case)",
476 	  SymName(actual(y)));
477       }
478       DetachGalley(y);
479       Parent(index, Up(y));
480       MoveLink(Up(index), NextDown(start_search), PARENT);
481       Link(tinners, index);
482     }
483     debug0(DGF, D, "  calling FlushInners() from TransferEnd (a)");
484     FlushInners(tinners, nilobj);
485   }
486 
487   /* flush any galleys inside hd */
488   if( inners != nilobj )
489   {
490     debug0(DGF, D, "  calling FlushInners() from TransferEnd (b)");
491     FlushInners(inners, nilobj);
492   }
493 
494   /* close dest_index, and flush parent galley if needed */
495   if( blocked(dest_index) )
496   { Parent(y, Up(dest_index));
497     DeleteNode(dest_index);
498     debug0(DGF, D, "  calling FlushGalley from TransferEnd");
499     FlushGalley(y);
500   }
501   else DeleteNode(dest_index);
502 
503   /* pop target stack and exit */
504   DisposeObject(targets[itop--]);
505   debug0(DGT, D, "] ] TransferEnd returning.");
506   ifdebug(DGT, DD, debug_targets());
507 } /* end TransferEnd */
508 
509 /*@::TransferClose()@*********************************************************/
510 /*                                                                           */
511 /*  TransferClose()                                                          */
512 /*                                                                           */
513 /*  Close this module.                                                       */
514 /*                                                                           */
515 /*****************************************************************************/
516 
TransferClose(void)517 void TransferClose(void)
518 { OBJECT inners;
519   debug0(DGT, D, "[ TransferClose()");
520   ifdebug(DGT, DD, debug_targets());
521   debug0(DGA, D, "  calling FreeGalley from TransferClose");
522   if( LastDown(root_galley) != root_galley )
523   { inners = nilobj;
524     FreeGalley(root_galley, root_galley, &inners, nilobj, nilobj);
525     if( inners != nilobj )
526     {
527       debug0(DGF, D, "  calling FlushInners() from TransferClose");
528       FlushInners(inners, nilobj);
529     }
530     debug0(DGF, D, "  calling FlushGalley from TransferClose");
531     FlushGalley(root_galley);
532   }
533   debug0(DGT, D, "] TransferClose returning.");
534 }
535