home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / APPS / lout2.lzh / LOUT2 / z25.c < prev    next >
Text File  |  1994-01-23  |  21KB  |  761 lines

  1. /*@z25.c:Object Echo:aprint(), cprint(), printnum()@**************************/
  2. /*                                                                           */
  3. /*  LOUT: A HIGH-LEVEL LANGUAGE FOR DOCUMENT FORMATTING (VERSION 2.05)       */
  4. /*  COPYRIGHT (C) 1993 Jeffrey H. Kingston                                   */
  5. /*                                                                           */
  6. /*  Jeffrey H. Kingston (jeff@cs.su.oz.au)                                   */
  7. /*  Basser Department of Computer Science                                    */
  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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA.                */
  24. /*                                                                           */
  25. /*  FILE:         z25.c                                                      */
  26. /*  MODULE:       Object Echo                                                */
  27. /*  EXTERNS:      EchoObject(), PrintObject()                                */
  28. /*                                                                           */
  29. /*****************************************************************************/
  30. #include "externs"
  31. #if DEBUG_ON
  32.  
  33. static    int    limit;            /* column where newline is needed    */
  34. static    int    indent;            /* current indent                    */
  35. static    int    col;            /* current output column             */
  36. static    FILE    *fp;            /* current output file               */
  37.  
  38. #define    moveright()    (indent += 3)
  39. #define    moveleft()    (indent -= 3)
  40.  
  41.  
  42. /*****************************************************************************/
  43. /*                                                                           */
  44. /*  static aprint(x)                                                         */
  45. /*  static cprint(x)                                                         */
  46. /*                                                                           */
  47. /*  Print the ASCII or FULL_CHAR string x onto the appropriate output.       */
  48. /*                                                                           */
  49. /*****************************************************************************/
  50.  
  51. static cprint(x)
  52. FULL_CHAR *x;
  53. { col += StringLength(x);
  54.   if( fp == null ) AppendString(x);
  55.   else StringFPuts(x, fp);
  56. } /* end print */
  57.  
  58. static aprint(x)
  59. char *x;
  60. { cprint(AsciiToFull(x));
  61. } /* end aprint */
  62.  
  63.  
  64. /*****************************************************************************/
  65. /*                                                                           */
  66. /*  static printnum(x)                                                       */
  67. /*                                                                           */
  68. /*  Print the number x onto the appropriate output.                          */
  69. /*                                                                           */
  70. /*****************************************************************************/
  71.  
  72. static printnum(x)
  73. int x;
  74. { cprint(StringInt(x));
  75. } /* end printnum */
  76.  
  77.  
  78. /*@::tab(), newline(), space()@***********************************************/
  79. /*                                                                           */
  80. /*  static tab(x)                                                            */
  81. /*                                                                           */
  82. /*  Tab to column x, or anyway insert at least one space.                    */
  83. /*                                                                           */
  84. /*****************************************************************************/
  85.  
  86. static tab(x)
  87. int x;
  88. {  do
  89.      aprint(" ");
  90.    while( col < x );
  91. } /* end tab */
  92.  
  93.  
  94. /*****************************************************************************/
  95. /*                                                                           */
  96. /*  static newline()                                                         */
  97. /*                                                                           */
  98. /*  Echo a newline to the appropriate output (unless output is a string).    */
  99. /*  Correct indenting and right limits are maintained, if possible.          */
  100. /*                                                                           */
  101. /*****************************************************************************/
  102.  
  103. static newline()
  104. { if( fp == null )  AppendString(STR_SPACE);
  105.   else
  106.   { fputs("\n", fp);
  107.     fflush(fp);
  108.     for( col = 0;  col < indent;  col++ )  fputs(" ", fp);
  109.   }
  110. } /* end newline */
  111.  
  112.  
  113. /*****************************************************************************/
  114. /*                                                                           */
  115. /*  static space(n)                                                          */
  116. /*                                                                           */
  117. /*  Echo n spaces to the appropriate output.                                 */
  118. /*  Correct indenting and right limits are maintained, if possible.          */
  119. /*                                                                           */
  120. /*****************************************************************************/
  121.  
  122. static space(n)
  123. int n;
  124. { int i;
  125.   if( fp == null )
  126.     for( i = 0;  i < n;  i++ )  AppendString(STR_SPACE);
  127.   else if( col + n > limit )
  128.   { fputs("\n", fp);
  129.     for( col = 0;  col < n-1;  col++ )  fputs(" ", fp);
  130.   }
  131.   else for( i = 0;  i < n;  col++, i++ )  fputs(" ", fp);
  132. } /* end space */
  133.  
  134.  
  135. /*@::echo()@******************************************************************/
  136. /*                                                                           */
  137. /*  static echo(x, outer_prec)                                               */
  138. /*                                                                           */
  139. /*  Echo x.  The result will be enclosed in braces only if its precedence    */
  140. /*  is less than or equal to outer_prec (words and parameterless closures    */
  141. /*  are taken to have infinite precedence, i.e. never enclosed in braces).   */
  142. /*                                                                           */
  143. /*****************************************************************************/
  144.  
  145. static echo(x, outer_prec)
  146. OBJECT x;  unsigned outer_prec;
  147. { OBJECT link, y, tmp, sym;
  148.   char *op;  int prec, i;
  149.   BOOLEAN npar_seen, name_printed, lbr_printed, braces_needed;
  150.  
  151.   switch( type(x) )
  152.   {
  153.  
  154.     case DEAD:
  155.  
  156.     aprint("#dead");
  157.     break;
  158.  
  159.     case UNATTACHED:
  160.     
  161.     aprint( "#unattached " );
  162.     moveright();
  163.     if( Down(x) != x )
  164.     { Child(y, Down(x));
  165.       if( y != x ) echo(y, NO_PREC);
  166.       else aprint("<child is self!>");
  167.     }
  168.     else aprint("<no child!>");
  169.     moveleft();
  170.     break;
  171.  
  172.  
  173.     case EXPAND_IND:
  174.     case GALL_PREC:
  175.     case GALL_FOLL:
  176.     case GALL_TARG:
  177.     case CROSS_PREC:
  178.     case CROSS_FOLL:
  179.     case CROSS_TARG:
  180.     case RECURSIVE:
  181.     
  182.     aprint("#"); cprint(Image(type(x))); aprint(" ");
  183.     echo(actual(x), NO_PREC);
  184.     break;
  185.  
  186.         
  187.     case RECEPTIVE:
  188.     case RECEIVING:
  189.     
  190.     aprint(type(x) == RECEIVING ? "#receiving " : "#receptive ");
  191.     if( external(actual(x)) )  aprint("(external) ");
  192.     if( threaded(actual(x)) )  aprint("(threaded) ");
  193.     if( blocked(x) )           aprint("(blocked) " );
  194.     if( trigger_externs(x) )   aprint("(trigger_externs) " );
  195.     if( non_blocking(x) )      aprint("(non_blocking) " );
  196.     cprint( type(actual(x)) == CLOSURE ?
  197.         SymName(actual(actual(x))) : Image(type(actual(x))) );
  198.     aprint(" ");
  199.     for( link = Down(x);  link != x;  link = NextDown(link) )
  200.     { Child(y, link);
  201.       moveright();
  202.       echo(y, NO_PREC);
  203.       moveleft();
  204.     }
  205.     break;
  206.  
  207.  
  208.     case PRECEDES:
  209.     
  210.     aprint("#precedes");
  211.     break;
  212.  
  213.  
  214.     case FOLLOWS:
  215.     
  216.     aprint("#follows");
  217.     if( blocked(x) )  aprint(" (blocked)");
  218.     Child(y, Down(x));
  219.     if( Up(y) == LastUp(y) )  aprint(" (no precedes!)");
  220.     break;
  221.  
  222.  
  223.     case HEAD:
  224.     
  225.     aprint("Galley ");  cprint(SymName(actual(x)));
  226.     aprint(" into ");   cprint(SymName(whereto(x)));
  227.     for( link = Down(x);  link != x;  link = NextDown(link) )
  228.     { Child(y, link);
  229.       newline();
  230.       echo(y, type(y) == GAP_OBJ ? VCAT : VCAT_PREC);
  231.     }
  232.     break;
  233.  
  234.  
  235.     case ROW_THR:
  236.  
  237.     aprint("{R ");
  238.     for( link = Down(x);  link != x;  link = NextDown(link) )
  239.     { Child(y, link);
  240.       echo(y, VCAT_PREC);
  241.       newline();
  242.       if( NextDown(link) != x )  aprint("/R ");
  243.     }
  244.     aprint("R}");
  245.     break;
  246.  
  247.  
  248.     case COL_THR:
  249.  
  250.     aprint("{C ");
  251.     for( link = Down(x);  link != x;  link = NextDown(link) )
  252.     { Child(y, link);
  253.       echo(y, HCAT_PREC);
  254.       newline();
  255.       if( NextDown(link) != x )  aprint("|C ");
  256.     }
  257.     aprint("C}");
  258.     break;
  259.  
  260.  
  261.     case VCAT: op = "/", prec = VCAT_PREC;  goto ETC;
  262.     case HCAT: op = "|", prec = HCAT_PREC;  goto ETC;
  263.     case ACAT: op = "&", prec = ACAT_PREC;  goto ETC;
  264.     
  265.     ETC:
  266.     if( Down(x) == x )
  267.     { aprint(op);
  268.       aprint("<empty>");
  269.       break;
  270.     }
  271.     if( prec <= outer_prec ) aprint("{ ");
  272.     /* *** if( Down(x) == LastDown(x) )  aprint(op);  must be manifested */
  273.     for( link = Down(x);  link != x;  link = NextDown(link) )
  274.     { Child(y, link);
  275.       if( is_index(type(y)) )
  276.         newline();
  277.       else if( (type(y) == GAP_OBJ && type(x) != ACAT) )
  278.         newline();
  279.       if( type(y) == GAP_OBJ )  echo(y, type(x));
  280.       else echo(y, prec);
  281.     }
  282.     if( prec <= outer_prec )  aprint(" }");
  283.     break;
  284.  
  285.  
  286.     case GAP_OBJ:
  287.  
  288.     /* in this case the outer_prec argument is VCAT, HCAT or ACAT */
  289.     if( Down(x) != x )
  290.     { if( outer_prec == ACAT )  aprint(" ");
  291.       cprint( EchoCatOp(outer_prec, mark(gap(x)), join(gap(x))) );
  292.       Child(y, Down(x));
  293.       echo(y, FORCE_PREC);
  294.       aprint(" ");
  295.     }
  296.     else if( outer_prec == ACAT )
  297.     { for( i = 1;  i <= vspace(x);  i++ )  newline();
  298.       for( i = 1;  i <= hspace(x);  i++ )  aprint(" ");
  299.     }
  300.     else
  301.     { cprint( EchoCatOp(outer_prec, mark(gap(x)), join(gap(x))) );
  302.       cprint( EchoGap(&gap(x)) );
  303.       aprint(" ");
  304.     }
  305.     break;
  306.  
  307.  
  308.     case WORD:
  309.     
  310.     if( StringLength(string(x)) == 0 )
  311.       aprint("{}");
  312.     else cprint( string(x) );
  313.     break;
  314.  
  315.  
  316.     case QWORD:
  317.     
  318.     cprint( StringQuotedWord(x) );
  319.     break;
  320.  
  321.  
  322.     case ENV:
  323.     
  324.     /* debug only */
  325.     aprint("<");
  326.     for( link = Down(x);  link != x;  link = NextDown(link) )
  327.     { Child(y, link);
  328.       if( type(y) == CLOSURE )
  329.       { cprint( SymName(actual(y)) );
  330.         echo(GetEnv(y), NO_PREC);
  331.       }
  332.       else if( type(y) == ENV )  echo(y, NO_PREC);
  333.       else cprint(Image(type(y)));
  334.       if( NextDown(link) != x )  aprint(" ");
  335.     }
  336.     aprint(">");
  337.     break;
  338.  
  339.  
  340.     case CROSS:
  341.  
  342.     assert( Down(x) != x, "echo: CROSS Down(x)!" );
  343.     Child(y, Down(x));
  344.     if( type(y) == CLOSURE )  cprint(SymName(actual(y)));
  345.     else
  346.     { cprint(KW_LBR);
  347.       echo(y, NO_PREC);
  348.       cprint(KW_RBR);
  349.     }
  350.     cprint(KW_CROSS);
  351.     if( NextDown(Down(x)) != x )
  352.     { Child(y, NextDown(Down(x)));
  353.       echo(y, NO_PREC);
  354.     }
  355.     else aprint("??");
  356.     break;
  357.  
  358.  
  359.     case CLOSURE:
  360.     
  361.     sym = actual(x);
  362.     braces_needed =
  363.         precedence(sym) <= outer_prec && (has_lpar(sym) || has_rpar(sym));
  364.  
  365.     /* print brace if needed */
  366.     if( braces_needed )  aprint("{ ");
  367.  
  368.     npar_seen = FALSE;  name_printed = FALSE;
  369.     for( link = Down(x); link != x;  link = NextDown(link) )
  370.     { Child(y, link);
  371.       if( type(y) == PAR )
  372.       { assert( Down(y) != y, "EchoObject: Down(PAR)!" );
  373.         switch( type(actual(y)) )
  374.         {
  375.          case LPAR:    Child(tmp, Down(y));
  376.             echo(tmp, (unsigned) precedence(sym));
  377.             aprint(" ");
  378.             break;
  379.  
  380.          case NPAR:    if( !name_printed )
  381.             { cprint(SymName(sym));
  382.               if( external(x) || threaded(x) )
  383.               { aprint(" #");
  384.                 if( external(x) )  aprint(" external");
  385.                 if( threaded(x) )  aprint(" threaded");
  386.                 newline();
  387.               }
  388.               name_printed = TRUE;
  389.             }
  390.             newline();  aprint("  ");
  391.             cprint( SymName(actual(y)) );
  392.             aprint(" { ");
  393.             Child(tmp, Down(y));
  394.             echo(tmp, NO_PREC);
  395.             aprint(" }");
  396.             npar_seen = TRUE;
  397.             break;
  398.  
  399.          case RPAR:    if( !name_printed )
  400.             { cprint(SymName(sym));
  401.               if( external(x) || threaded(x) )
  402.               { aprint(" #");
  403.                 if( external(x) )  aprint(" external");
  404.                 if( threaded(x) )  aprint(" threaded");
  405.                 newline();
  406.               }
  407.               name_printed = TRUE;
  408.             }
  409.             if( npar_seen ) newline();
  410.             else aprint(" ");
  411.             Child(tmp, Down(y));
  412.             if( has_body(sym) )
  413.             { aprint("{ ");
  414.               echo(tmp, NO_PREC);
  415.               aprint(" }");
  416.             }
  417.             else echo(tmp, (unsigned) precedence(sym));
  418.             break;
  419.     
  420.          default:    Error(INTERN, &fpos(y), "echo: %s",
  421.                     Image(type(actual(y))) );
  422.             break;
  423.  
  424.         }
  425.       }
  426.     }
  427.     if( !name_printed )
  428.     { cprint( SymName(sym) );
  429.       if( external(x) || threaded(x) )
  430.       { aprint(" #");
  431.         if( external(x) )  aprint(" external");
  432.         if( threaded(x) )  aprint(" threaded");
  433.         newline();
  434.       }
  435.     }
  436.  
  437.     /* print closing brace if needed */
  438.     if( braces_needed ) aprint(" }");
  439.     break;
  440.  
  441.  
  442.     case SPLIT:
  443.     
  444.     /* this should occur only in debug output case */
  445.     cprint(KW_SPLIT);  moveright();
  446.     Child(y, DownDim(x, COL));
  447.     aprint(" ");
  448.     echo(y, FORCE_PREC);
  449.     moveleft();
  450.     break;
  451.  
  452.  
  453.     case PAR:
  454.     
  455.     /* this should occur only in debug output case */
  456.     aprint("par ");  cprint(SymName(actual(x)));
  457.     break;
  458.  
  459.  
  460.     case CR_LIST:
  461.  
  462.     aprint("(");
  463.     for( link = Down(x);  link != x;  link = NextDown(link) )
  464.     { Child(y, link);
  465.       echo(y, NO_PREC);
  466.       if( NextDown(link) != x )  aprint(", ");
  467.     }
  468.     aprint(")");
  469.     break;
  470.  
  471.  
  472.     case MACRO:
  473.     
  474.     newline();  cprint(KW_MACRO);
  475.     aprint(" ");  cprint(SymName(x));
  476.     if( sym_body(x) != nil )
  477.     { newline();  cprint(KW_LBR);
  478.       y = sym_body(x);
  479.       do
  480.       { for( i = 1;  i <= vspace(y);  i++ )  newline();
  481.         for( i = 1;  i <= hspace(y);  i++ )  aprint(" ");
  482.         cprint(EchoToken(y));
  483.         y = succ(y, PARENT);
  484.       } while( y != sym_body(x) );
  485.       newline();  aprint(KW_RBR);
  486.     }
  487.     else aprint(" {}");
  488.     if( visible(x) )  aprint(" # (visible)");
  489.     break;
  490.  
  491.  
  492.     case NPAR:
  493.     case LOCAL:
  494.     
  495.     /* print predefined operators in abbreviated form */
  496.     if( sym_body(x) == nil && enclosing(x) != nil )
  497.     { tab(3); aprint("# sys ");
  498.       cprint(SymName(x));
  499.       break;
  500.     }
  501.  
  502.     /* print def line and miscellaneous debug info */
  503.     if( type(x) == LOCAL ) newline();
  504.     cprint(type(x) == NPAR ? KW_NAMED : KW_DEF);
  505.     aprint(" ");  cprint( SymName(x) );
  506.     if( recursive(x) || indefinite(x) || visible(x) ||
  507.         is_extern_target(x) || uses_extern_target(x) || uses_galley(x) )
  508.     { tab(25);  aprint("#");
  509.       if( visible(x)  )  aprint(" visible");
  510.       if( recursive(x)  )  aprint(" recursive");
  511.       if( indefinite(x) )  aprint(" indefinite");
  512.       if( is_extern_target(x) )  aprint(" is_extern_target");
  513.       if( uses_extern_target(x) )  aprint(" uses_extern_target");
  514.       if( uses_galley(x) )  aprint(" uses_galley");
  515.     }
  516.  
  517.     /* print uses list, if necessary */
  518.     if( uses(x) != nil || dirty(x) )
  519.     { newline();  aprint("   # ");
  520.       if( dirty(x) ) aprint("dirty, ");
  521.       aprint("uses");
  522.       if( uses(x) != nil )
  523.       { tmp = next(uses(x));
  524.         do
  525.         { aprint(" "), cprint( SymName(item(tmp)) );
  526.           tmp = next(tmp);
  527.         } while( tmp != next(uses(x)) );
  528.       }
  529.       /* ***
  530.       for( tmp = uses(x);  tmp != nil;  tmp = next(tmp) )
  531.       { aprint(" "), cprint( SymName(item(tmp)) );
  532.       }
  533.       *** */
  534.     }
  535.  
  536.     /* print precedence, if necessary */
  537.     if( precedence(x) != DEFAULT_PREC )
  538.     { newline();  aprint("   ");  cprint(KW_PRECEDENCE);
  539.       aprint(" ");  printnum(precedence(x));
  540.     }
  541.  
  542.     /* print associativity, if necessary */
  543.     if( !right_assoc(x) )
  544.     { newline();  aprint("   ");
  545.       cprint(KW_ASSOC);  aprint(" ");  cprint(KW_LEFT);
  546.     }
  547.  
  548.     /* print named parameters and local objects */
  549.     lbr_printed = FALSE;
  550.     for( link = Down(x);  link != x;  link = NextDown(link) )
  551.     { Child(y, link);
  552.       assert( enclosing(y) == x, "echo: enclosing(y) != x!" );
  553.       switch( type(y) )
  554.       {
  555.         case LPAR:
  556.         case RPAR:    newline();  aprint("   ");
  557.             cprint( type(y) == LPAR ? KW_LEFT :
  558.                 has_body(x) ? KW_BODY : KW_RIGHT);
  559.             aprint(" ");
  560.             cprint( SymName(y) );
  561.             aprint("   # uses_count = ");
  562.             printnum(uses_count(y));
  563.             if( visible(y) )  aprint(" (visible)");
  564.             break;
  565.  
  566.         case NPAR:    moveright();  newline();
  567.             echo(y, NO_PREC);
  568.             aprint("   # uses_count = ");
  569.             printnum(uses_count(y));
  570.             moveleft();
  571.             break;
  572.  
  573.         case MACRO:
  574.         case LOCAL:    if( !lbr_printed )
  575.             { newline();
  576.               cprint(KW_LBR);
  577.               lbr_printed = TRUE;
  578.             }
  579.             moveright();
  580.             echo(y, NO_PREC);
  581.             moveleft();  newline();
  582.             break;
  583.  
  584.         default:    Error(FATAL, &fpos(y), "echo: type(y) = %s",
  585.                     Image(type(y)));
  586.             break;
  587.       }
  588.     }
  589.     if( type(x) == NPAR && Down(x) == x )  aprint(" ");
  590.     else newline();
  591.     if( !lbr_printed )
  592.     { cprint(KW_LBR);  aprint("  ");
  593.       lbr_printed = TRUE;
  594.     }
  595.     else aprint("   ");
  596.  
  597.     /* print body */
  598.     moveright();
  599.     if( sym_body(x) != nil )  echo(sym_body(x), NO_PREC);
  600.     moveleft();  if( type(x) == LOCAL ) newline();
  601.     cprint(KW_RBR);
  602.     break;
  603.  
  604.  
  605.     case ONE_COL:
  606.     case ONE_ROW:
  607.     case HCONTRACT:
  608.     case VCONTRACT:
  609.     case HEXPAND:
  610.     case VEXPAND:
  611.     case PADJUST:
  612.     case HADJUST:
  613.     case VADJUST:
  614.     case HSCALE:
  615.     case VSCALE:
  616.     case NEXT:
  617.     case WIDE:
  618.     case HIGH:
  619.     case INCGRAPHIC:
  620.     case SINCGRAPHIC:
  621.     case GRAPHIC:
  622.     case ROTATE:
  623.     case SCALE:
  624.     case CASE:
  625.     case YIELD:
  626.     case XCHAR:
  627.     case FONT:
  628.     case SPACE:
  629.     case BREAK:
  630.     case OPEN:
  631.     case TAGGED:
  632.     
  633.     /* print enclosing left brace if needed */
  634.     braces_needed = (DEFAULT_PREC <= outer_prec);
  635.     if( braces_needed )  cprint(KW_LBR), aprint(" ");
  636.  
  637.     /* print left parameter */
  638.     if( Down(x) != LastDown(x) )
  639.     { Child(y, Down(x));
  640.       echo(y, max(outer_prec, DEFAULT_PREC));
  641.       aprint(" ");
  642.     }
  643.  
  644.     cprint(Image(type(x)));
  645.  
  646.     /* print right parameter */
  647.     assert( LastDown(x) != x, "echo: right parameter of predefined!" );
  648.     aprint(" ");
  649.     Child(y, LastDown(x));
  650.     echo(y, type(x)==OPEN ? FORCE_PREC : max(outer_prec,DEFAULT_PREC));
  651.     if( braces_needed )  aprint(" "), cprint(KW_RBR);
  652.     break;
  653.  
  654.  
  655.     case NULL_CLOS:
  656.     
  657.     cprint(Image(type(x)));
  658.     break;
  659.  
  660.  
  661.     case CR_ROOT:
  662.  
  663.     for( link = Down(x);  link != x;  link = NextDown(link) )
  664.     { Child(y, link);
  665.       echo(y, NO_PREC);  newline();
  666.     }
  667.     break;
  668.  
  669.  
  670.     case CROSS_SYM:
  671.  
  672.     aprint("Cross-references for ");
  673.     cprint(SymName(symb(x)));  newline();
  674.     switch( target_state(x) )
  675.     {
  676.       case 0:    aprint("NO_TARGET");
  677.             break;
  678.  
  679.       case 1:    aprint("SEEN_TARGET ");
  680.             printnum(target_seq(x));
  681.             aprint(": ");
  682.             echo(target_val(x), NO_PREC);
  683.             break;
  684.  
  685.       case 2:    aprint("WRITTEN_TARGET ");
  686.             printnum(target_seq(x));
  687.             aprint(": to file ");
  688.             cprint(FileName(target_file(x)));
  689.             aprint(" at ");
  690.             printnum(target_pos(x));
  691.             break;
  692.     
  693.       default:    aprint("ILLEGAL!");
  694.             break;
  695.     }
  696.     newline();
  697.     for( link = Down(x);  link != x;  link = NextDown(link) )
  698.     { Child(y, link);
  699.       aprint("   ");
  700.       if( gall_rec(y) )  aprint("gall_rec!");
  701.       else cprint(string(y));
  702.       newline();
  703.     }
  704.     break;
  705.  
  706.  
  707.     default:
  708.     
  709.     Error(INTERN, no_fpos, "echo found %s", Image(type(x)));
  710.     break;
  711.  
  712.   } /* end switch */
  713. } /* end echo */
  714.  
  715.  
  716. /*@::EchoObject(), DebugObject()@*********************************************/
  717. /*                                                                           */
  718. /*  FULL_CHAR *EchoObject(x)                                                 */
  719. /*                                                                           */
  720. /*  Return an image of unsized object x in result.                           */
  721. /*                                                                           */
  722. /*****************************************************************************/
  723.  
  724. FULL_CHAR *EchoObject(x)
  725. OBJECT x;
  726. { debug0(DOE, D, "EchoObject()");
  727.   fp = null;;
  728.   col = 0;
  729.   indent = 0;
  730.   limit  = 60;
  731.   if( fp == null )
  732.   BeginString();
  733.   if( x == nil )  AppendString(AsciiToFull("<nil>"));
  734.   else echo(x, type(x) == GAP_OBJ ? VCAT : 0);
  735.   debug0(DOE, D, "EchoObject returning");
  736.   return EndString();
  737. } /* end EchoObject */
  738.  
  739.  
  740. /*****************************************************************************/
  741. /*                                                                           */
  742. /*  DebugObject(x)                                                           */
  743. /*                                                                           */
  744. /*  Send an image of unsized object x to result.                             */
  745. /*                                                                           */
  746. /*****************************************************************************/
  747.  
  748. DebugObject(x)
  749. OBJECT x;
  750. { debug0(DOE, D, "DebugObject()");
  751.   fp = stderr;
  752.   col = 0;
  753.   indent = 0;
  754.   limit  = 60;
  755.   if( x == nil )  fprintf(stderr, "<nil>");
  756.   else echo(x, type(x) == GAP_OBJ ? VCAT : 0);
  757.   fprintf(stderr, "\n");
  758.   debug0(DOE, D, "DebugObject returning");
  759. } /* end DebugObject */
  760. #endif
  761.