trl_dump.c
上传用户:dgyhgb
上传日期:2007-01-07
资源大小:676k
文件大小:31k
源码类别:

SQL Server

开发平台:

Unix_Linux

  1. /*
  2.  *  trl_dump.c  - support library for dumping and reading tree of 
  3.  *                GNU SQL compiler
  4.  *
  5.  *  This file is a part of GNU SQL Server
  6.  *
  7.  *  Copyright (c) 1996, 1997, Free Software Foundation, Inc
  8.  *  Developed at the Institute of System Programming
  9.  *  This file is written by Michael Kimelman
  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 2 of the License, or
  14.  *  (at your option) 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.  *  Contacts: gss@ispras.ru
  26.  *
  27.  */
  28. /* $Id: trl_dump.c,v 1.246 1997/03/31 11:01:48 kml Exp $ */
  29. #include <assert.h>
  30. #include "trl.h"
  31. #include "trlinter.h"
  32. #include "tree_gen.h"
  33. #include "type_lib.h"
  34. /*******==================================================*******
  35. *******      Printing trn for debugging dumps.             *******
  36. *******==================================================*******/
  37. static i4_t vcb_dump_in_progress = 0;
  38. static FILE *outfl = NULL;
  39. char spaces[]=
  40. "                                                                            "
  41. "                                                                            "
  42. "                                                                            "
  43. "                                                                            "
  44.  ;
  45. static i4_t sawclose = 0;
  46. static i4_t backlay = 0;
  47. static i4_t just_for_info = 0;
  48. #define PRINT_INDENT fprintf (outfl, "n%s%s", (just_for_info?";;":""),
  49.                               spaces + sizeof spaces - indent*2)
  50. #define INC_INDENT indent+=1
  51. #define DEC_INDENT indent-=1
  52. /* Print IN_TRN onto OUTFL.  This is the recursive part of printing.  */
  53. static void
  54. print_trn (trn in_trn, char type_mode,i4_t go_right)
  55. {
  56.   static i4_t indent = 1;
  57.   static i4_t clr_pattern = 0;
  58.   static i4_t check_integrity = 1;
  59.   register enum token code;
  60.   register i4_t i, j, sc, type_vcb_subtree = 1;
  61.   register char *format_ptr;
  62.   TXTREF   lvr = TNULL;
  63.   TXTREF parm;
  64.   i4_t printback, jfi = 0;
  65.   trn in_trn1 = in_trn;
  66.   printback = 0;
  67.   if (type_mode == 'P')
  68.     type_mode = 't';
  69.   if (indent < 0)
  70.     indent = 0;
  71.   sc = 0;
  72.   if (in_trn)
  73.     code = in_trn->code;
  74.   else
  75.     code = NIL_CODE;
  76.   if (code <= UNKNOWN || code >= LAST_TOKEN)
  77.     {
  78.       sc = code;
  79.       code = UNKNOWN;
  80.     }
  81.   if (code == SKIP_CODE)
  82.     {
  83.       fputs (" - ", outfl);
  84.       goto GO_RIGHT;
  85.     }
  86.   else if (code == SKIP_CODES)
  87.     {
  88.       fputs (" -- ", outfl);
  89.       goto GO_RIGHT;
  90.     }
  91.   /* print name of expression code */
  92.   if (code <= NIL_CODE)
  93.     {
  94.       fprintf (outfl, " (%s)", NAME (code));
  95.       if (sc)
  96.         {
  97.           fprintf (outfl, "  ;; !!!!! code value ==%d", sc);
  98.           sawclose = 1;
  99.         }
  100.       return;
  101.     }
  102.   else if (Tstf_TRN (in_trn, MARK_F))
  103.     {
  104.       fprintf (outfl, " (%s:mark_f)", NAME (code));
  105.       return; 
  106.       /* goto GO_RIGHT; */
  107.     }
  108.   
  109.   if (sawclose)
  110.     {
  111.       PRINT_INDENT;
  112.       sawclose = 0;
  113.     }
  114.   else
  115.     PRINT_INDENT;
  116.   if (Is_statement(in_trn))
  117.     {
  118.       PRINT_INDENT;
  119.       fprintf (outfl, ";;-------------------------------");
  120.       PRINT_INDENT;
  121.     }
  122. #if 0
  123.   fprintf (outfl, "(/*%p*/%s",in_trn, NAME (code));
  124. #else
  125.   fprintf (outfl, "(%s",NAME (code));
  126. #endif
  127.   /* print flags */
  128.   i = MASk_TRN (in_trn) & (FLAG_VALUE (VCB_F) - 1);
  129.   if (i)
  130.     fprintf (outfl, ":%d", i - 1);
  131.   for (i = VCB_F; i < LAST_FLAG; i++)
  132.     if (compatible_tok_fl (code, (enum flags) i))
  133.       if (Tstf_TRN (in_trn, (enum flags) i))
  134. if ((i != PATTERN_F) || (clr_pattern == 0))
  135.   fprintf (outfl, ":%s", NAME_FL ((enum flags) i));
  136.   fputs ("  ", outfl);
  137.   if (Is_statement(in_trn) || (code==VIEW))
  138.     {
  139.       register TXTREF v;
  140.       lvr = LOCAL_VCB_ROOT;
  141. #if 0
  142.       v = XVCb_TRN (in_trn, 7);
  143.       if ( v || go_right)
  144.         LOCAL_VCB_ROOT = v;
  145. #else
  146.       LOCAL_VCB_ROOT = (code==VIEW?VIEw_VCB(in_trn):XVCb_TRN (in_trn, 7));
  147. #endif
  148.       for (v = LOCAL_VCB_ROOT; v; v = RIGHT_TRN (v))
  149. {
  150.   if (TstF_TRN(v,MARK1_F))
  151.             {
  152.               ClrF_TRN (v, MARK1_F);
  153.               yyerror("? ?");
  154.               errors--;
  155.             }
  156. }
  157.     }
  158.   
  159.   if (Is_table (in_trn) || (code==SCAN))
  160.     {
  161.       if (!Tstf_TRN (in_trn, MARK1_F))
  162.         Setf_TRN (in_trn, MARK1_F);
  163.       else /* if (code!=SCAN) */
  164.         type_vcb_subtree = 0;
  165.     }
  166.   if (Tstf_TRN(in_trn,VCB_F) && check_integrity && (Is_table (in_trn) || (code==SCAN)))
  167.     {
  168.       TXTREF v;
  169.       if ((code == SCAN) || (code==TMPTABLE))
  170.         v = LOCAL_VCB_ROOT;
  171.       else
  172.         v = VCB_ROOT;
  173.       for (; v; v = RIGHT_TRN(v))
  174.         if ( Ptree(v) == in_trn )
  175.           break;
  176.       if (!v) /* IF node not found in vocabulary */
  177.         {
  178.           check_integrity = 0;
  179.           trl_wrn("vcb node not in vcb list",__FILE__,__LINE__,in_trn);
  180.         }
  181.     }
  182.   Setf_TRN (in_trn, MARK_F);
  183.   format_ptr = FORMAT (code);
  184.   for (i = 0; i < LENGTH (code); i++, format_ptr++)
  185.     {
  186.       
  187. #define TST_PAT_BIT(n) TST_BIT(XLNg_TRN(in_trn,PTRN_OP(code,n)),PTRN_BIT(n))
  188.       
  189.       if ( Tstf_TRN(in_trn,ACTION_F) && TST_PAT_BIT(i) )
  190.         {
  191.           fprintf(outfl," <%s> ",STRING(XLTr_TRN(in_trn,i)));
  192.           continue;
  193.         }
  194.       if ((!type_vcb_subtree) && (*format_ptr != 's') &&
  195.           ((code!=SCAN) || (*format_ptr!='t') ))
  196.         continue;
  197.       
  198.       if ((type_vcb_subtree) && (*format_ptr == 'V') &&
  199.           (code==SCAN) && XTXt_TRN(in_trn,i))
  200.         {
  201.           just_for_info++; jfi = 1; /* type scolumn list */
  202.           goto case_n;
  203.         }
  204.       
  205.       switch (*format_ptr)
  206.         {
  207.         case 's':
  208.         case 'S':
  209.           sawclose = 0;
  210.           if (XLTr_TRN (in_trn, i) == 0)
  211.             fprintf (outfl, " """);
  212.           else
  213.             {
  214.               fprintf (outfl, " "%s"", STRING (XLTr_TRN (in_trn, i)));
  215.               sawclose = 1;
  216.             }
  217.           break;
  218.           /* 0 indicates a field for internal use that should not be printed.  */
  219.         case '0':
  220.         case 'r':
  221.         case 'a':
  222.         case 'd':
  223.           break;
  224.         case 'V': /* special vocabulary reference (backward link) */
  225.           if (backlay == 0)
  226.             break;
  227.           printback++;
  228.           backlay--;
  229.         case 't':
  230.         case 'P': /* pattern tree */
  231.         case 'v':
  232.           if ((type_mode == 't') || (*format_ptr == 't') || (*format_ptr == 'P'))
  233.             {
  234.               i4_t old_clr_pat = clr_pattern;
  235.               INC_INDENT;
  236.               if (!sawclose)
  237.                 fprintf (outfl, " ");
  238.               if (*format_ptr == 'P')
  239.                 clr_pattern = 1;
  240.               if (type_vcb_subtree)
  241.                 print_trn (Ptree (XTXt_TRN (in_trn, i)), *format_ptr,0);
  242.               else
  243.                 fprintf (outfl, " (nil /**/)");
  244.               DEC_INDENT;
  245.               clr_pattern = old_clr_pat;
  246.             }
  247.           if (printback)
  248.             {
  249.               backlay++;
  250.               printback--;
  251.             }
  252.           break;
  253.         case 'p':
  254.           if (!Tstf_TRN (in_trn, PATTERN_F))
  255.             {
  256.               fprintf (outfl, " line:%d", (i4_t) LOCATIOn_TRN (in_trn));
  257.               sawclose = 0;
  258.             }
  259.           break;
  260.         case 'y':
  261.           {
  262.             char s[20];
  263.             conv_type (s, &XOp_TRN (in_trn, i).type, 0);
  264.             fprintf (outfl, " %s", s);
  265.             sawclose = 0;
  266.           }
  267.           break;
  268.         case 'i':
  269.           fprintf (outfl, " %d", (i4_t) XLNg_TRN (in_trn, i));
  270.           sawclose = 0;
  271.           break;
  272.         case 'x':
  273.           fprintf (outfl, " %x", XLNg_TRN (in_trn, i));
  274.           sawclose = 0;
  275.           break;
  276.         case 'l':
  277.           fprintf (outfl, " %d", XLNg_TRN (in_trn, i));
  278.           sawclose = 0;
  279.           break;
  280.         case 'R':
  281.           fprintf (outfl, " R:%d", XLNg_TRN (in_trn, i));
  282.           sawclose = 0;
  283.           break;
  284.         case 'f':
  285.           fprintf (outfl, " %f", XFLt_TRN (in_trn, i));
  286.           sawclose = 0;
  287.           break;
  288.         case 'T':
  289.         case 'L':
  290.           INC_INDENT;
  291.           if (TNULL != XVEc_TRN (in_trn, i) && type_vcb_subtree)
  292.             {
  293.               TXTREF vec = XVEc_TRN (in_trn, i);
  294.               sc = 0;
  295.               if (*format_ptr == 'T')
  296.                 if (VLEN (vec))
  297.                   sc = 1;
  298.               if (sawclose || sc)
  299.                 {
  300.                   PRINT_INDENT;
  301.                   sawclose = sc;
  302.                 }
  303.               fprintf (outfl, " [");
  304.               INC_INDENT;
  305.               if (VLEN (vec) == 0)
  306.                 {
  307.                   fprintf (outfl, "n;; vector lenght =%d ", VLEN (vec));
  308.                   PRINT_INDENT;
  309.                 }
  310.               for (j = 0; j < VLEN (vec); j++)
  311.                 {
  312.                   switch (*format_ptr)
  313.                     {
  314.                     case 'T':
  315.                       print_trn (Ptree ((VOP (vec, j).txtp)), 't',0);
  316.                       break;
  317.                     case 'L':
  318.                       fprintf (outfl, " %d", VOP (vec, j).l);
  319.                       if (j % 5 == 4)
  320.                         {
  321.                           PRINT_INDENT;
  322.                           sawclose = 1;
  323.                         }
  324.                       break;
  325.                     default:
  326.                       fprintf (outfl, "n;; unexpected format");
  327.                       PRINT_INDENT;
  328.                       /**/ ;
  329.                     }
  330.                 }
  331.               DEC_INDENT;
  332.               sawclose += sc;
  333.               if (sawclose)
  334.                 PRINT_INDENT;
  335.               if (sawclose)
  336.                 fprintf (outfl, "]");
  337.               else
  338.                 fprintf (outfl, " ]");
  339.             }
  340.           else
  341.             fprintf (outfl, " [] ");
  342.           sawclose = 1;
  343.           DEC_INDENT;
  344.           break;
  345.         case 'N':
  346.           if (XTXt_TRN(in_trn,i)==TNULL || !type_vcb_subtree)
  347.             fprintf (outfl," >><< ");
  348.           else
  349.             {
  350.             case_n:
  351.               PRINT_INDENT;
  352.               INC_INDENT;
  353.               sawclose = 1;
  354.               fprintf (outfl," >> ");
  355.               print_trn (Ptree (XTXt_TRN(in_trn, i)), 't',1);
  356.               DEC_INDENT;
  357.               if (sawclose)
  358.                 PRINT_INDENT;
  359.               if (sawclose)
  360.                 fprintf (outfl, "<<");
  361.               else
  362.                 fprintf (outfl, " <<");
  363.               PRINT_INDENT;
  364.               sawclose = 0;
  365.             }
  366.           break;
  367.         default:
  368.           fprintf (STDERR,
  369.                    "Internal error %s:%d:(print_trn) format '%c' wrongn",
  370.                    __FILE__, __LINE__, *format_ptr);
  371.           yyfatal (" Abort");
  372.         }
  373.       if(jfi)
  374.         {
  375.           just_for_info-=jfi;
  376.           jfi = 0;
  377.           PRINT_INDENT;
  378.         }
  379.     }
  380.   /* print comparision pattern */
  381.   if (Tstf_TRN (in_trn, PATTERN_F))
  382.     {
  383.       i4_t k;
  384.       k = PTRN_ELEM (code);
  385.       i = LENGTH (code) + k - 1;
  386.       while (k--)
  387. fprintf (outfl, " %X", (u4_t) XLNg_TRN (in_trn, i - k));
  388.     }
  389.   /* print parameters */
  390.   fputs (" ", outfl);
  391.   if (HAS_DOWn (in_trn))
  392.     {
  393.       INC_INDENT;
  394.       PRINT_INDENT; sawclose = 0; 
  395.       fprintf (outfl, "{ ");
  396.       INC_INDENT;
  397.       if (ARITy_TRN (in_trn))
  398. sawclose = 1;
  399.       for (i = ARITy_TRN (in_trn), parm = DOWn_TRN (in_trn);
  400.    i && parm;
  401.    parm = RIGHT_TRN (parm), i--);
  402.       if (i || parm)
  403. {
  404.   fprintf (outfl, "n;; node parameters number mismath ");
  405.   sawclose = 1;
  406.           /* ARITY correcting */
  407.           for (; parm; parm = RIGHT_TRN (parm))
  408.             (ARITy_TRN (in_trn))++;
  409.           ARITy_TRN (in_trn) -= i;
  410. }
  411.       print_trn (Ptree (DOWn_TRN(in_trn)), 't',1);
  412.       DEC_INDENT;
  413.       if (sawclose)
  414. PRINT_INDENT;
  415.       fprintf (outfl, "} ");
  416.       sawclose = 1;
  417.       DEC_INDENT;
  418.     }
  419.   fprintf (outfl, ")");
  420.   sawclose = 1;
  421.   if ( Is_statement(in_trn) || (code==VIEW))
  422.     {
  423.       register TXTREF v;
  424.       vcb_dump_in_progress = 1;
  425.       /* backlay=1; */
  426.       if (dump_vocabulary)
  427. fprintf (outfl, "n;; ==========<< Local Vocabulary >>===============");
  428.       for (v = LOCAL_VCB_ROOT; v; v = RIGHT_TRN (v))
  429. {
  430.   if (TstF_TRN(v,MARK1_F))
  431.     ClrF_TRN (v, MARK1_F);
  432. }
  433.       if (dump_vocabulary)
  434. {
  435.   fprintf (outfl, "n");
  436.   print_trn (Ptree (XVCb_TRN (in_trn, 7)), 't',1);
  437. }
  438.       /* backlay=0; */
  439.       vcb_dump_in_progress = 0;
  440.       if(code==VIEW)
  441.         { assert(VIEw_VCB(in_trn) == LOCAL_VCB_ROOT); }
  442.       else
  443.         { assert(XVCb_TRN (in_trn, 7) == LOCAL_VCB_ROOT); }
  444.       LOCAL_VCB_ROOT = lvr;
  445.     }
  446.   assert (in_trn == in_trn1);
  447. GO_RIGHT:
  448.   if (go_right && RIGHt_TRN(in_trn))
  449.     print_trn (Ptree(RIGHt_TRN(in_trn)),type_mode,go_right);
  450.   Clrf_TRN (in_trn, MARK_F);
  451. #undef PRINT_INDENT
  452. #undef INC_INDENT
  453. #undef DEC_INDENT
  454. }
  455. /* Call this function from the debugger to see what X looks like.  */
  456. void
  457. toggle_mark1f(i4_t i)
  458. {
  459.   TXTREF v;
  460.   for (v = VCB_ROOT; v; v = RIGHT_TRN (v))
  461.     if (i)
  462.       SetF_TRN (v, MARK1_F);
  463.     else
  464.       ClrF_TRN (v, MARK1_F);
  465.   for (v = LOCAL_VCB_ROOT; v; v = RIGHT_TRN (v))
  466.     if (i)
  467.       SetF_TRN (v, MARK1_F);
  468.     else
  469.       ClrF_TRN (v, MARK1_F);
  470. }
  471. void
  472. debug_trn_d (trn x)
  473. {
  474.   FILE *of;
  475.   static i4_t prevent_loop = 0;
  476.   if (prevent_loop)
  477.     {
  478.       fprintf (STDERR, ";; debug loop encountered --> BREAK n");
  479.       return; 
  480.     }
  481.   prevent_loop++;    
  482.   vcb_dump_in_progress = 1;
  483.   of = outfl;
  484.   outfl = STDERR;
  485.   /* backlay=1; */
  486.   sawclose = 1;
  487.   if (x)
  488.     {
  489.       MASKTYPE m = MASk_TRN (x);
  490.       if (Tstf_TRN (x, MARK_F))
  491. {
  492.   Clrf_TRN (x, MARK_F);
  493.   fprintf (STDERR, ";; node below is marked n");
  494. }
  495.       print_trn (x, 't',0);
  496.       MASk_TRN (x) = m;
  497.     }
  498.   else
  499.     fprintf (STDERR, "(nil_code)n");
  500.   fprintf (STDERR, "n");
  501.   vcb_dump_in_progress = 0;
  502.   backlay = 0;
  503.   toggle_mark1f(0);
  504.   outfl = of;
  505.   prevent_loop--;
  506. }
  507. void
  508. debug_trn (TXTREF x)
  509. {
  510.   debug_trn_d (Ptree (x));
  511. #if 0
  512.   if (!x)
  513.     return;
  514.   if ( Is_Statement(x))
  515.     {
  516.       TXTREF v,v1;
  517.       fprintf(STDERR,"Local vocabulary ...n");
  518.       for (v1 = STMT_VCB(x); v1; v1 = RIGHT_TRN (v1))
  519.         {
  520.           debug_trn_d (Ptree (v1));
  521.           for (v = STMT_VCB(x); v; v = RIGHT_TRN (v))
  522.             if (TstF_TRN(v,MARK1_F))
  523.               ClrF_TRN (v, MARK1_F);
  524.         }
  525.       fprintf(STDERR,"======================n");
  526.     }
  527. #endif
  528. }
  529. /* External entry point for printing a chain of statements
  530.  * starting with ROOT onto file OUTF.                    
  531.  * A blank line separates insns.                         
  532.  */
  533. void
  534. print_trl (TXTREF trn_first, FILE * outf)
  535. {
  536.   register TXTREF cur_stmt;
  537.   outfl = outf;
  538.   if (outfl == NULL)
  539.     outfl = STDOUT;
  540.   sawclose = 1;
  541.   if (trn_first)
  542.     print_trn (Ptree (trn_first), 't',0);
  543.   else
  544.     {
  545.       print_trn (Ptree (ROOT), 't',1);
  546.       fprintf (outfl, "nn;;--------------------------------------------nn");
  547.       
  548.       if (dump_vocabulary)
  549.         {
  550.           vcb_dump_in_progress = 1;
  551.           /* backlay=1; */
  552.           fprintf (outfl, ";; ==========<< Global Vocabulary >>===============");
  553.           print_trn (Ptree (VCB_ROOT), 't',1);
  554.           backlay = 0;
  555.           vcb_dump_in_progress = 0;
  556.         }
  557.     }
  558.   for (cur_stmt = VCB_ROOT; cur_stmt; cur_stmt = RIGHT_TRN (cur_stmt))
  559.     if (TstF_TRN(cur_stmt,MARK1_F))
  560.       ClrF_TRN (cur_stmt, MARK1_F);
  561.   outfl = NULL;
  562. }
  563. /*******==================================================*******
  564. *******             Reading trn from file                  *******
  565. *******==================================================*******/
  566. /* Subroutines of read_trn.  */
  567. /* Dump code after printing a message.  Used when read_trn finds invalid
  568.    data.  */
  569. static FILE *infile = NULL;
  570. static i4_t line_num = 0;
  571. static void
  572. ftail (void)
  573. {
  574.   i4_t c, i;
  575.   fprintf (STDERR, "nFollowing characters are:nt");
  576.   for (i = 0; i < 200; i++)
  577.     {
  578.       c = getc (infile);
  579.       if (EOF == c)
  580. break;
  581.       putc (c, STDERR);
  582.     }
  583.   fprintf (STDERR, "Aborting.n");
  584.   abort ();
  585. }
  586. static void
  587. dump_and_abort (i4_t expected_c, i4_t actual_c)
  588. #define CHECK_CHAR(SYMBOL)  if(c!=SYMBOL) dump_and_abort(SYMBOL,c)
  589. {
  590.   fprintf (STDERR,
  591.    "Expected :'%c'. Read: '%c'. At file position:%ld",
  592.    expected_c, actual_c, ftell (infile));
  593.   if (line_num)
  594.     {
  595.       fprintf (STDERR, " %s:%d:", progname ? progname : "", line_num);
  596.       line_num = 0;
  597.     }
  598.   ftail ();
  599. }
  600. /* Read chars from INFILE until a non-whitespace char and return that.
  601.    Comments, both Lisp style and C style, are treated as whitespace. Tools
  602.    such as gen* use this function.  */
  603. int
  604. read_skip_spaces (void)
  605. {
  606.   register i4_t c;
  607.   while ((c = getc (infile)) != EOF)
  608.     {
  609.       if (c == ' ' || c == 't' || c == 'f')
  610. continue;
  611.       else if (c == 'n')
  612. line_num++;
  613.       else if (c == ';')
  614. {
  615.   while ((c = getc (infile)) != EOF && c != 'n');
  616.   if (c == 'n')
  617.     line_num++;
  618. }
  619.       else if (c == '/')
  620. {
  621.   register i4_t prevc;
  622.   c = getc (infile);
  623.   CHECK_CHAR ('*');
  624.   prevc = 0;
  625.   while ((c = getc (infile)) != EOF)
  626.     {
  627.       if (prevc == '*' && c == '/')
  628. break;
  629.       prevc = c;
  630.     }
  631. }
  632.       else
  633. break;
  634.     }
  635.   return c;
  636. }
  637. /* Read an trn code name into the buffer STR[]. It is terminated by any of
  638.    the punctuation chars of trn printed syntax.  */
  639. static void
  640. read_name (char *str)
  641. {
  642.   register char *p;
  643.   register i4_t c;
  644.   c = read_skip_spaces ();
  645.   p = str;
  646.   while (1)
  647.     {
  648.       if (c == ' ' || c == 'n' || c == 't' || c == 'f')
  649. break;
  650.       if (c == ':' || c == '"' || c == '/' || c == '[' || c == ']'
  651.   || c == '(' || c == ')' || c == '{' || c == '}'
  652. )
  653. {
  654.   ungetc (c, infile);
  655.   break;
  656. }
  657.       *p++ = c;
  658.       c = getc (infile);
  659.     }
  660.   if (c == 'n')
  661.     line_num++;
  662.   *p = 0;
  663. }
  664. static LTRLREF
  665. get_literal(char *terminators,i4_t *cp)
  666. {
  667.   i4_t saw_paren = 0;
  668.   register i4_t j,c; 
  669.   register char *buf;
  670.   i4_t            bufsize;
  671.   
  672. #define EXIT(val)  { LTRLREF v=val; *cp = c; if(buf) xfree(buf); return v;}
  673.   
  674.   bufsize = 10;
  675.   buf = (char *) xmalloc (bufsize + 1);
  676.   c = getc (infile);
  677.   if (c == '(' ) 
  678.     {
  679.       saw_paren = 1;
  680.       c = read_skip_spaces ();
  681.     }
  682.   else if (c == '-')
  683.     EXIT(TNULL);
  684.   CHECK_CHAR (terminators[0]);
  685.   j = 0;
  686.   while (1)
  687.     {
  688.       if (j >= bufsize - 4)
  689. {
  690.   bufsize *= 2;
  691.   buf = (char *) xrealloc (buf, bufsize + 1);
  692. }
  693.       buf[j] = getc (infile); /* Read the string  */
  694.       if (buf[j] == '\')
  695. {
  696.   buf[j] = getc (infile); /* Read the string  */
  697.   switch(buf[j])
  698.     {
  699.     case 'n': buf[j] = 'n'; break;
  700.     case 't': buf[j] = 't'; break;
  701.     case 'b': buf[j] = 'b'; break;
  702.     case 'f': buf[j] = 'f'; break;
  703.     case 'r': buf[j] = 'r'; break;
  704.     default:               ; break;
  705.     }
  706. }
  707.       else if (buf[j] == terminators[1])
  708. break;
  709.       j++;
  710.     }
  711.   buf[j] = 0; /* NUL terminate the string  */
  712.   if (saw_paren)
  713.     {
  714.       c = read_skip_spaces ();
  715.       CHECK_CHAR (')');
  716.     }
  717.   
  718.   if (*buf)
  719.     EXIT(ltr_rec (buf));
  720.   EXIT(TNULL);
  721. #undef EXIT
  722. }
  723. /*
  724.  * Read an trn in printed representation from INFILE and return an actual trn
  725.  * in core constructed accordingly. read_trn is not used in the compiler
  726.  * proper, but rather in tools (kitty) and for debugging purpose
  727.  */
  728. static MASKTYPE default_mask = 0;
  729. static TXTREF
  730. read_trn_l (void)
  731. {
  732.   register i4_t i, j, list_counter;
  733.   enum token tmp_code;
  734.   register char *format_ptr;
  735.   /* tmp_char is a buffer used for reading decimal integers and names of trn
  736.      types and machine modes. Therefore, 256 must be enough.  */
  737.   char tmp_char[256];
  738.   TXTREF return_trn;
  739.   MASKTYPE msk;
  740.   i4_t c;
  741.   i4_t minus = 0;
  742.   c = read_skip_spaces (); /* Should be open paren.  */
  743.   if (c == EOF)
  744.     return TNULL;
  745.   return_trn = TNULL;
  746.   if (c == '-') /* special construction for omitted nodes '-'
  747.    and '--' */
  748.     {
  749.       while (1)
  750. {
  751.   c = getc (infile);
  752.   switch (c)
  753.     {
  754.     case '}':
  755.       ungetc (c, infile);
  756.     case ' ':
  757.     case 'n':
  758.     case 't':
  759.     case 'f':
  760.     case 'r':
  761.       if (return_trn == TNULL)
  762. return gen_node1 (SKIP_CODE, default_mask);
  763.       return return_trn;
  764.     case '-':
  765.       if (return_trn)
  766. dump_and_abort (' ', '-');
  767.       else
  768. return_trn = gen_node1 (SKIP_CODES, default_mask);
  769.       break;
  770.     default:
  771.       dump_and_abort (' ', c);
  772.     }
  773. }
  774.       /* unreachable code */
  775.     }
  776.   if (c == 'O') /* looks like Op:n construction */
  777.     {
  778.       minus = 1;
  779.       ungetc (c, infile);
  780.     }
  781.   else
  782.     CHECK_CHAR ('(');
  783.   read_name (tmp_char);
  784.   /* fprintf(STDERR,"Name '%s' is readn",tmp_char); */
  785.   tmp_code = UNKNOWN;
  786.   for (i = UNKNOWN; i < NUM_TRN_CODE; i++) /* @@ might speed this search
  787.    up */
  788.     {
  789.       if (!strcmp (tmp_char, NAME (i)))
  790. {
  791.   tmp_code = (enum token) i; /* get value for name */
  792.   break;
  793. }
  794.     }
  795.   if (tmp_char[0] == '-')
  796.     tmp_code = NIL_CODE;
  797.   if (tmp_code == UNKNOWN)
  798.     {
  799.       fprintf (STDERR,
  800.        "Unknown trn read in trl.read_trn_l(). Code name was '%s' .n",
  801.        tmp_char);
  802.       ftail ();
  803.     }
  804.   /* (NIL_CODE) stands for an expression that isn't there.  */
  805.   if (tmp_code == NIL_CODE)
  806.     {
  807.       /* Discard the closeparen.  */
  808.       while ((c = getc (infile)) != EOF && c != ')');
  809.       return TNULL;
  810.     }
  811.   /* If what follows is `: flag ', read it and store the flags in the trn.  */
  812.   c = read_skip_spaces ();
  813.   msk = 0;
  814.   while (c == ':')
  815.     {
  816.       read_name (tmp_char);
  817.       for (i = LAST_FLAG - 1; i >= VCB_F; i--)
  818. if (compatible_tok_fl (tmp_code, (enum flags) i))
  819.   if (!strcmp (tmp_char, NAME_FL (i)))
  820.     {
  821.       SetF (msk, (enum flags) i);
  822.       break;
  823.     }
  824.       if (i < VCB_F)
  825. if ((*tmp_char >= '0') && (*tmp_char <= '9'))
  826.   {
  827.     i4_t v;
  828.     if (1 == sscanf (tmp_char, "%d", &v))
  829.       msk |= (v > 14 ? 0 : v + 1);
  830.     else
  831.       yyerror ("Unexpected 'op' flagn");
  832.   }
  833. else
  834.   {
  835.     fprintf (STDERR, "trl_read: unrecognized flag '%s' in line %dn",
  836.      tmp_char, line_num);
  837.     errors++;
  838.   }
  839.       c = read_skip_spaces ();
  840.     }
  841.   ungetc (c, infile);
  842.   msk |= default_mask;
  843.   return_trn = gen_node1 (tmp_code, msk);
  844.   if ((tmp_code == OPERAND) && minus)
  845.     return return_trn;
  846. #define SET_PAT_BIT(n) 
  847.   SET_BIT(XLNG_TRN(return_trn,PTRN_OP(tmp_code,n)),PTRN_BIT(n))
  848. #define ATR_IS_READ if(msk) SET_PAT_BIT(i);
  849.   
  850.   msk = TstF (msk, PATTERN_F);
  851.   format_ptr = FORMAT (tmp_code);
  852.   for (i = 0, format_ptr = FORMAT (tmp_code);
  853.        i < (LENGTH (tmp_code) + (msk ? PTRN_ELEM (tmp_code) : 0));
  854.        i++, format_ptr++)
  855.     {
  856.       c = read_skip_spaces ();
  857.       ungetc (c, infile);
  858.       if (c == ')' || c == '{')
  859. break;
  860.       if (c=='<')
  861. {
  862.   if(!TstF_TRN(return_trn,ACTION_F))
  863.     yyfatal("Unexpected external reference in dump");
  864.   switch(*format_ptr)
  865.     {
  866.     case '0': case 'r': case 'd': case 'a': case 'V':  case 'p':
  867.       break;
  868.     default:
  869.       SET_PAT_BIT (i);
  870.       if (msk)
  871. SET_PAT_BIT (i+LENGTH(tmp_code));
  872.       XLTR_TRN(return_trn,i) = get_literal("<>",&c);
  873.     }
  874.   continue;
  875. }
  876.       if (i >= LENGTH (tmp_code))
  877. format_ptr = "x";
  878.       switch (*format_ptr)
  879. {
  880.   /* 0 means a field For internal use only. Don't expect it to be
  881.      present in the input.  */
  882. case '0':
  883. case 'r': /* right, down and arity field must be filled */
  884. /* later */
  885. case 'a':
  886. case 'd':
  887.   break;
  888. case 'V': /* special vocabulary reference (backward */
  889. /* link) */
  890.   break;
  891. case 't':
  892. case 'v':
  893.   {
  894.     register TXTREF x = read_trn_l ();
  895.     if (msk)
  896.       if (CODE_TRN (x) == SKIP_CODE)
  897. {
  898.   free_node (x);
  899.   x = TNULL;
  900. }
  901.       else
  902. SET_PAT_BIT (i);
  903.     XTXT_TRN (return_trn, i) = x;
  904.   }
  905.   break;
  906. case 'P': /* pattern tree */
  907.   {
  908.     MASKTYPE x = default_mask;
  909.     SetF (default_mask, PATTERN_F);
  910.     XTXT_TRN (return_trn, i) = read_trn_l ();
  911.     ATR_IS_READ;
  912.     default_mask = x;
  913.     break;
  914.   }
  915. case 'N':  /* '>> () ... () <<' as a simple reference */
  916.   {
  917.     register TXTREF cn = TNULL;
  918.     CHECK_CHAR('>');
  919.     c = getc(infile);
  920.     CHECK_CHAR('>');
  921.     c = getc(infile);
  922.     CHECK_CHAR('>');
  923.     for(;;)
  924.       {
  925. c = read_skip_spaces ();
  926. if (c == '<')
  927.   break;
  928. ungetc (c, infile);
  929. if (cn)
  930.   cn = RIGHT_TRN(cn) = read_trn_l();
  931. else
  932.   cn = XTXT_TRN(return_trn,i) = read_trn_l();
  933.       }
  934.     CHECK_CHAR('<');
  935.     c = getc(infile);
  936.     CHECK_CHAR('<');
  937.     break;
  938.   }    
  939. case 'S':
  940.   /* 'S' is an optional string: If a closeparen follows, just store
  941.      NULL For this element.  */
  942.   if ((c != '"') && (c != '(') && (c != '-')) /* " */
  943.     {
  944.       XLTR_TRN (return_trn, i) = 0;
  945.       break;
  946.     }
  947. case 's': 
  948.   {
  949.     XLTR_TRN(return_trn,i) = get_literal("""",&c) ;
  950.     if (c == '-')
  951.       break;
  952.     ATR_IS_READ;
  953.     break;
  954.   }
  955. case 'p':
  956.   {
  957.     if (c == 'l')
  958.       {
  959. i4_t p = 0;
  960. CHECK_CHAR ('l');
  961. fscanf (infile, "line:%d", &p);
  962. LOCATION_TRN (return_trn) = p;
  963.       }
  964.     else
  965.       LOCATION_TRN (return_trn) = line_num;
  966.     break;
  967.   }    
  968. case 'y':
  969.   {
  970.     if (c == '-')
  971.       {
  972. if (msk)
  973.   c = getc (infile);
  974. else
  975.   yyerror ("Warning: unexpected - in dump");
  976.       }
  977.     else
  978.       {
  979. sql_type_t t;
  980. char       s[50];
  981. fscanf (infile, "%[^ tnfr]", s);
  982. conv_type (s, &t, 1);
  983. XOP_TRN (return_trn, i).type = t;
  984. ATR_IS_READ;
  985.     }
  986.     break;
  987.   }
  988. case 'i':
  989.   {
  990.     if (msk && (c == '-'))
  991.       {
  992. c = getc (infile);
  993. break;
  994.       }
  995.     read_name (tmp_char);
  996.     XLNG_TRN (return_trn, i) = atoi (tmp_char);
  997.     ATR_IS_READ;
  998.     break;
  999.   }
  1000. case 'x':
  1001.   {
  1002.     if (msk && (c == '-'))
  1003.       {
  1004. c = getc (infile);
  1005. break;
  1006.       }
  1007.     fscanf (infile, "%X", (u4_t *) &(XLNG_TRN (return_trn, i)));
  1008.     if (i < LENGTH (tmp_code))
  1009.       ATR_IS_READ;
  1010.     break;
  1011.   }
  1012. case 'l':
  1013.   {
  1014.     if (msk && (c == '-'))
  1015.       {
  1016. c = getc (infile);
  1017. break;
  1018.       }
  1019.     read_name (tmp_char);
  1020.     XLNG_TRN (return_trn, i) = atol (tmp_char);
  1021.     ATR_IS_READ;
  1022.     break;
  1023.   }
  1024. case 'R':
  1025.   {
  1026.     i4_t l;
  1027.     if (msk && (c == '-'))
  1028.       {
  1029. c = getc (infile);
  1030. break;
  1031.       }
  1032.     fscanf (infile, "R:%d", &l);
  1033.     XLNG_TRN (return_trn, i) = l;
  1034.     ATR_IS_READ;
  1035.     break;
  1036.   }
  1037. case 'f':
  1038.   {
  1039.     if (msk && (c == '-'))
  1040.       {
  1041. c = getc (infile);
  1042. break;
  1043.       }
  1044.     read_name (tmp_char);
  1045.     XFLT_TRN (return_trn, i) = atof (tmp_char);;
  1046.     ATR_IS_READ;
  1047.     break;
  1048.   }
  1049. case 'T':
  1050. case 'L':
  1051.   {
  1052.     struct trn_list
  1053.     {
  1054.       struct trn_list *next;
  1055.       tr_union value;
  1056.     };
  1057.     register struct trn_list *next_trn, *trn_list_link;
  1058.     struct trn_list *list_trn = NULL;
  1059.     if (msk && (c == '-'))
  1060.       {
  1061. c = getc (infile);
  1062. break;
  1063.       }
  1064.     c = read_skip_spaces ();
  1065.     CHECK_CHAR ('[');
  1066.     /* add expressions to a list, while keeping a count */
  1067.     next_trn = NULL;
  1068.     list_counter = 0;
  1069.     while ((c = read_skip_spaces ())!= EOF && c != ']')
  1070.       {
  1071. ungetc (c, infile);
  1072. list_counter++;
  1073. trn_list_link = 
  1074.   (struct trn_list *)xmalloc (sizeof (struct trn_list));
  1075. switch (*format_ptr)
  1076.   {
  1077.   case 'T':
  1078.     trn_list_link->value.txtp = read_trn_l ();
  1079.     break;
  1080.   case 'L':
  1081.     read_name (tmp_char);
  1082.     trn_list_link->value.l = atol (tmp_char);
  1083.     break;
  1084.   }
  1085. if (next_trn == 0)
  1086.   list_trn = trn_list_link;
  1087. else
  1088.   next_trn->next = trn_list_link;
  1089. next_trn = trn_list_link;
  1090. trn_list_link->next = 0;
  1091.       }
  1092.     /* get vector length and allocate it */
  1093.     if (list_counter > 0)
  1094.       {
  1095. XVEC_TRN (return_trn, i) = gen_vect (list_counter);
  1096. next_trn = list_trn;
  1097. for (j = 0; j < list_counter; j++, next_trn = next_trn->next)
  1098.   XOP_VEC (return_trn, i, j) = next_trn->value;
  1099. while (list_trn)
  1100.   {
  1101.     next_trn = list_trn;
  1102.     list_trn = list_trn->next;
  1103.     xfree (next_trn);
  1104.   }
  1105.       }
  1106.     /* close bracket gotten */
  1107.     ATR_IS_READ;
  1108.     break;
  1109.   }
  1110. default:
  1111.   {
  1112.     fprintf (STDERR,
  1113.      "%ld: Internal error:(trn_read) format '%c' wrongn",
  1114.      ftell (infile), format_ptr[-1]);
  1115.     yyfatal ("Abort");
  1116.   }
  1117. }
  1118.     }
  1119.   c = read_skip_spaces ();
  1120.   ungetc (c, infile);
  1121.   if (HAS_DOWN (return_trn) && ((c == '{') /* || (msk==0) */ ))
  1122.     {
  1123.       register TXTREF next_trn;
  1124.       TXTREF list_trn = TNULL;
  1125.       
  1126.       c = read_skip_spaces ();
  1127.       CHECK_CHAR ('{');
  1128.       
  1129.       /* add expressions to a list, while keeping a count */
  1130.       next_trn = TNULL;
  1131.       list_counter = 0;
  1132.       while ((c = read_skip_spaces ())!= EOF && c != '}')
  1133. {
  1134.   ungetc (c, infile);
  1135.   list_counter++;
  1136.   
  1137.   list_trn = read_trn_l ();
  1138.   if (next_trn == 0)
  1139.     DOWN_TRN (return_trn) = list_trn;
  1140.   else
  1141.     RIGHT_TRN (next_trn) = list_trn;
  1142.   next_trn = list_trn;
  1143. }
  1144.       ARITY_TRN (return_trn) = list_counter;
  1145.       /* close bracket gotten */
  1146.     }
  1147.   
  1148.   c = read_skip_spaces ();
  1149.   CHECK_CHAR (')');
  1150.   /* add vocabulary information */
  1151.   if (TstF_TRN (return_trn, VCB_F) && !TstF_TRN(return_trn,ACTION_F) )
  1152.     {
  1153.       TXTREF tmp_trn = return_trn;
  1154.       switch (tmp_code)
  1155. {
  1156. case PARAMETER:
  1157. case CURSOR:
  1158.   return_trn = add_info_l (return_trn);
  1159.   if (return_trn != tmp_trn)
  1160.     free_tree (tmp_trn);
  1161.   break;
  1162. case SCAN:
  1163.   return_trn = find_entry (return_trn);
  1164.   if (return_trn)
  1165.     free_tree (tmp_trn);
  1166.   else
  1167.     {
  1168.       return_trn = tmp_trn;
  1169.       RIGHT_TRN (tmp_trn) = LOCAL_VCB_ROOT;
  1170.       LOCAL_VCB_ROOT = tmp_trn;
  1171.     }
  1172.   break;
  1173. case SCOLUMN: /* link all backward reference */
  1174. case COLUMN:
  1175.   return_trn = add_info_l (return_trn);
  1176.   if (return_trn != tmp_trn)
  1177.     free_node (tmp_trn);
  1178.   break;
  1179. default:
  1180.   if (Is_Table (return_trn))
  1181.     {
  1182.       return_trn = add_info_l (return_trn);
  1183.       if (return_trn != tmp_trn)
  1184. free_tree (tmp_trn);
  1185.       else
  1186. {
  1187.   TXTREF clmn;
  1188.   for (clmn = TBL_COLS (return_trn); clmn; clmn = RIGHT_TRN (clmn))
  1189.     COL_TBL (clmn) = return_trn;
  1190. }
  1191.     } /* Is_Table */
  1192. }
  1193.     }
  1194.   if (Is_Statement (return_trn))
  1195.     {
  1196.       STMT_VCB (return_trn) = LOCAL_VCB_ROOT;
  1197.       LOCAL_VCB_ROOT = TNULL;
  1198.     }
  1199.   /*----------------------------*/
  1200.   if (TstF_TRN (return_trn, MARK_F))
  1201.     {
  1202.       free_node (return_trn);
  1203.       return_trn = TNULL;
  1204.     }
  1205.   return return_trn;
  1206. #undef ATR_IS_READ
  1207. #undef SET_PAT_BIT
  1208. }
  1209. #undef CHECK_CHAR
  1210. TXTREF
  1211. read_trn(FILE * infl,i4_t *line,MASKTYPE def_msk)
  1212. {
  1213.   MASKTYPE x;
  1214.   TXTREF   t;
  1215.   infile = infl;
  1216.   line_num = line ? *line: 0;
  1217.   x = default_mask;
  1218.   default_mask = def_msk;
  1219.   t = read_trn_l ();
  1220.   default_mask = x;
  1221.   if (line)
  1222.     *line = line_num;
  1223.   return t;
  1224. }
  1225. void
  1226. load_trl (FILE * infl)
  1227. {
  1228.   MASKTYPE x;
  1229.   install (NULL);
  1230.   infile = infl;
  1231.   line_num = 0;
  1232.   x = default_mask;
  1233.   default_mask = 0;
  1234.   LOCAL_VCB_ROOT = TNULL;
  1235.   for(;;)
  1236.     {
  1237.       register TXTREF st = read_trn_l ();
  1238.       if (!st)
  1239. break;
  1240.       add_statement (st);
  1241.     }
  1242.   default_mask = x;
  1243.   return;
  1244. }
  1245. void
  1246. load_trlfile (char *flname)
  1247. {
  1248.   FILE *fl = fopen (flname, "r");
  1249.   char *oldpn;
  1250.   if (!fl)
  1251.     {
  1252.       fprintf (STDERR, "Can't open '%s'n", flname);
  1253.       exit (FATAL_EXIT_CODE);
  1254.     }
  1255.   oldpn = progname;
  1256.   progname = flname;
  1257.   load_trl (fl);
  1258.   progname = oldpn;
  1259.   fclose (fl);
  1260. }