/*------------------------------------------------------------\
|                                                             |
| Tool    :                    GRAAL                          |
|                                                             |
| File    :                  GsbParse.c                       |
|                                                             |
| Authors :                Jacomme Ludovic                    |
|                                                             |
| Date    :                   01.08.93                        |
|                                                             |
\------------------------------------------------------------*/

/*------------------------------------------------------------\
|                                                             |
|                         Include Files                       |
|                                                             |
\------------------------------------------------------------*/

# include <malloc.h>
# include <stdlib.h>
# include <string.h>
# include MUT_H
# include MPH_H
# include RDS_H
# include RUT_H
# include RPR_H
# include GSB_H
# include "GSB_error.h"
# include "GSB_parse.h"

/*------------------------------------------------------------\
|                                                             |
|                           Constants                         |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                            Types                            |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                          Variables                          |
|                                                             |
\------------------------------------------------------------*/

  static char *GraalDefaultTechnoName = GRAAL_DEFAULT_TECHNO_NAME;

/*------------------------------------------------------------\
|                                                             |
|                       Table variables                       |
|                                                             |
\------------------------------------------------------------*/

  char  *GRAAL_VIA_NAME_TABLE[ MBK_MAX_VIA ][ 3 ];
  char  *GRAAL_SYMMETRY_NAME_TABLE[ MBK_MAX_SYMMETRY ][ 3 ];
  char  *GRAAL_ORIENT_NAME_TABLE[ MBK_MAX_ORIENT ][ 3 ];
  char  *GRAAL_REFERENCE_NAME_TABLE[ MBK_MAX_REFERENCE ][ 3 ];
  char  *GRAAL_SEGMENT_NAME_TABLE[ MBK_MAX_LAYER ][ 3 ];
  char  *GRAAL_CONNECTOR_NAME_TABLE[ MBK_MAX_LAYER ][ 3 ];
  char  *GRAAL_RDS_LAYER_NAME_TABLE[ RDS_MAX_LAYER ][ 3 ];

  long   GRAAL_SEGMENT_VALUE_TABLE[ MBK_MAX_LAYER ][ 2 ];
  long   GRAAL_PEEK_BOUND;
  float  GRAAL_LOWER_GRID_STEP;
  float  GRAAL_LOWER_FIGURE_STEP;
  float  GRAAL_LOWER_INSTANCE_STEP;
  float  GRAAL_LOWER_CONNECTOR_STEP;
  float  GRAAL_LOWER_SEGMENT_STEP;
  float  GRAAL_LOWER_REFERENCE_STEP;

  char  *GRAAL_NOT_DEFINE = "";

/*------------------------------------------------------------\
|                                                             |
|                      Keywords variables                     |
|                                                             |
\------------------------------------------------------------*/

  static char  KeywordDefined = 0;

  static char *DefineKeyword;
  static char *TableKeyword;
  static char *EndTableKeyword;
  static char *EndRecordKeyword;
  static char *PeekBoundKeyword;
  static char *LowerGridStepKeyword;
  static char *LowerFigureStepKeyword;
  static char *LowerInstanceStepKeyword;
  static char *LowerSegmentStepKeyword;
  static char *LowerReferenceStepKeyword;
  static char *LowerConnectorStepKeyword;
  static char *SegmentNameKeyword;
  static char *ConnectorNameKeyword;
  static char *SegmentValueKeyword;
  static char *ViaNameKeyword;
  static char *SymmetryNameKeyword;
  static char *OrientNameKeyword;
  static char *ReferenceNameKeyword;
  static char *RdsLayerNameKeyword;


  static keyword KeywordDefine[ GSB_MAX_KEYWORD ] =
 

  {
    { "alu1",         ALU1          },
    { "alu2",         ALU2          },
    { "alu3",         ALU3          },
    { "c_x_n",        C_X_N         },
    { "c_x_p",        C_X_P         },
    { "cont_body_n",  CONT_BODY_N   },
    { "cont_body_p",  CONT_BODY_P   },
    { "cont_dif_n",   CONT_DIF_N    },
    { "cont_dif_p",   CONT_DIF_P    },
    { "cont_poly",    CONT_POLY     },
    { "cont_via",     CONT_VIA      },
    { "cont_via2",    CONT_VIA2     },
    { "cont_via3",    CONT_VIA3     },
    { "east",         GRAAL_EAST    }, 
    { "ndif",         NDIF          },
    { "north",        GRAAL_NORTH   }, 
    { "nosym",        NOSYM         }, 
    { "ntie",         NTIE          },
    { "ntrans",       NTRANS        },
    { "nwell",        NWELL         },
    { "pdif",         PDIF          },
    { "poly",         POLY          },
    { "ptie",         PTIE          },
    { "ptrans",       PTRANS        },
    { "pwell",        PWELL         },
    { "rds_abox",     RDS_ABOX      },
    { "rds_activ",    RDS_ACTIV     },
    { "rds_alu1",     RDS_ALU1      },
    { "rds_alu2",     RDS_ALU2      },
    { "rds_alu3",     RDS_ALU3      },
    { "rds_alu4",     RDS_ALU4      },
    { "rds_cont",     RDS_CONT      },
    { "rds_cpas",     RDS_CPAS      },
    { "rds_gate",     RDS_GATE      },
    { "rds_ndif",     RDS_NDIF      },
    { "rds_nimp",     RDS_NIMP      },
    { "rds_ntie",     RDS_NTIE      },
    { "rds_nwell",    RDS_NWELL     },
    { "rds_pdif",     RDS_PDIF      },
    { "rds_pimp",     RDS_PIMP      },
    { "rds_poly",     RDS_POLY      },
    { "rds_ptie",     RDS_PTIE      },
    { "rds_pwell",    RDS_PWELL     },
    { "rds_ref",      RDS_REF       },
    { "rds_talu1",    RDS_TALU1     },
    { "rds_talu2",    RDS_TALU2     },
    { "rds_talu3",    RDS_TALU3     },
    { "rds_tpoly",    RDS_TPOLY     },
    { "rds_user0",    RDS_USER0     },
    { "rds_user1",    RDS_USER1     },
    { "rds_user2",    RDS_USER2     },
    { "rds_via1",     RDS_VIA1      },
    { "rds_via2",     RDS_VIA2      },
    { "rds_via3",     RDS_VIA3      },
    { "ref_con",      MBK_REF_CON   },
    { "ref_ref",      MBK_REF_REF   },
    { "rot_m",        ROT_M         },
    { "rot_p",        ROT_P         },
    { "south",        GRAAL_SOUTH   }, 
    { "sy_rm",        SY_RM         }, 
    { "sy_rp",        SY_RP         }, 
    { "sym_x",        SYM_X         },
    { "sym_y",        SYM_Y         },
    { "symxy",        SYMXY         },
    { "talu1",        TALU1         },
    { "talu2",        TALU2         },
    { "talu3",        TALU3         },
    { "tpoly",        TPOLY         },
    { "west",         GRAAL_WEST    }
  };

/*------------------------------------------------------------\
|                                                             |
|                       File variables                        |
|                                                             |
\------------------------------------------------------------*/

  static  FILE *GsbFile;
  static  char  GsbBuffer[ GSB_MAX_BUFFER ];
  static  long  GsbCurrentLine;

/*------------------------------------------------------------\
|                                                             |
|                          Functions                          |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                       Gsb File Get String                   |
|                                                             |
\------------------------------------------------------------*/

 char *GsbFileGetString( String, Size )

   char *String;
   int   Size;
 {
   register char *RegisterString;
   register       Register;

   RegisterString = String;

   while (--Size > 0 && (Register = getc( GsbFile )) != EOF )
   {
     if ((*RegisterString++ = Register) == '\\') 
     {
       if ((Register = getc( GsbFile )) == '\n') 
       {
         *(RegisterString - 1) = ' ';
       } 
       else
       {
         ungetc( Register, GsbFile );
       }
     }
     else
     {
       if ( Register == '\n') break;
     }
   }

   *RegisterString = '\0';

   return ( ( Register       == EOF    ) && 
            ( RegisterString == String ) ) ? (char *)NULL : String;
 }

/*------------------------------------------------------------\
|                                                             |
|                       Gsb File Get Line                     |
|                                                             |
\------------------------------------------------------------*/

 void GsbGetLine( Buffer )

   char   *Buffer;
 {
   char   *Check;
   char   *String;
   char    OneComment;

   do 
   {
     OneComment = 0;

     Check = GsbFileGetString( Buffer, GSB_MAX_BUFFER );

     if ( Check != (char *)NULL ) 
     {
       GsbCurrentLine++;
     }
     else 
     {
       GsbError( UNEXPECTED_EOF, (char *)NULL, GsbCurrentLine );
     }

     if ( String = strchr( Buffer, GSB_COMMENT_CHAR ))
     {
       if ( String == Buffer )
       {
         OneComment = 1;
       }
       else
       {
         *(String - 1) = '\0'; 
       }
     }
 
     while (*Buffer != '\0' && strchr( GSB_SEPARATORS_STRING, *Buffer))
     {
       Buffer = Buffer + 1;;
     }

     if (*Buffer == '\0') OneComment = 1;

   } 
   while ( OneComment == 1);
 }      

/*------------------------------------------------------------\
|                                                             |
|                        Gsb Check Keyword                    |
|                                                             |
\------------------------------------------------------------*/

 char GsbCheckKeyword( Word )

    char *Word;
 {
   if ( ( Word == DefineKeyword ) ||
        ( Word == TableKeyword  ) )
   {
     return 1;
   }
   else
   {
     return 0;
   }
 }

/*------------------------------------------------------------\
|                                                             |
|                        Gsb Get First word                   |
|                                                             |
\------------------------------------------------------------*/

 char *GsbGetFirstWord( Buffer, IsKeyword, Hash )
 
       char *Buffer;
       char  IsKeyword;
       char  Hash;
 {
   char   *String;
   char   *Text;
   int     Index;

   if ( String = (char *)strtok( Buffer, GSB_SEPARATORS_STRING )) 
   {
     if ( Hash )
     {
       String = namealloc( String );
     }
     else
     {
       Text = malloc( strlen( String ) + 1 );
       strcpy( Text, String );
       String = Text;

       for ( Index = 0; Text[ Index ]; Index++ )
       {
         if ( Text[ Index ] == '_' ) Text[ Index ] = ' '; 
       }
     }

     if ( ( IsKeyword ) && GsbCheckKeyword( String ) )
     {
       GsbError( UNEXPECTED_LINE, String, GsbCurrentLine );
     }
   }
   return( String );
 }

/*------------------------------------------------------------\
|                                                             |
|                        Gsb Get Next word                    |
|                                                             |
\------------------------------------------------------------*/

 char *GsbGetNextWord( IsKeyword, Hash )
 
       char IsKeyword;
       char Hash;
 {
   char   *String;
   char   *Text;
   int     Index;

   if ( String = (char *)strtok( (char *)NULL, GSB_SEPARATORS_STRING )) 
   {
      if ( Hash )
      {
        String = namealloc( String );
      }
      else
      {
        Text = malloc( strlen( String ) + 1 );
        strcpy( Text, String );
        String = Text;

        for ( Index = 0; Text[ Index ]; Index++ )
        {
          if ( Text[ Index ] == '_' ) Text[ Index ] = ' ';
        }
      }
  
      if ( ( IsKeyword ) && GsbCheckKeyword( String ) )
      {
        GsbError( UNEXPECTED_LINE, String, GsbCurrentLine );
      }
   }

   return( String );
 }

/*------------------------------------------------------------\
|                                                             |
|                      Gsb Keyword Compare                    |
|                                                             |
\------------------------------------------------------------*/

  int GsbKeywordCompare( FirstKey, SecondKey )

      keyword *FirstKey;
      keyword *SecondKey;
  {
    return strcmp( FirstKey->NAME, SecondKey->NAME );
  }

/*------------------------------------------------------------\
|                                                             |
|                      Gsb Get String Value                   |
|                                                             |
\------------------------------------------------------------*/

 long GsbGetStringValue( String )

    char     *String;
 {
   long      Value;
   keyword  *Keyword;
   keyword   Entry;

   if ( sscanf( String, "%d", &Value) )

     return ( Value );

   Entry.NAME = String;

   Keyword = (keyword *)bsearch( (char *)(&Entry), 
                                 (char *)KeywordDefine, 
                                 GSB_MAX_KEYWORD, sizeof( keyword ),
                                 GsbKeywordCompare );

   if ( Keyword != (keyword *)NULL ) return( Keyword->VALUE );

   GsbError( UNEXPECTED_LINE, String, GsbCurrentLine );
 }

/*------------------------------------------------------------\
|                                                             |
|                      Gsb Get String Float                   |
|                                                             |
\------------------------------------------------------------*/

 float GsbGetStringFloat( String )

    char     *String;
 {
   float     Value;
   keyword  *Keyword;
   keyword   Entry;

   if ( sscanf( String, "%g", &Value) )

     return ( Value );

   GsbError( ILLEGAL_FLOAT, String, GsbCurrentLine );
 }

/*------------------------------------------------------------\
|                                                             |
|                        Gsb Get Number                       |
|                                                             |
\------------------------------------------------------------*/

  long GsbGetNumber( String )

       char *String;
  {
    long Value;

    if ( sscanf( String, "%d", &Value )) return Value;

    GsbError( UNEXPECTED_LINE, "number", GsbCurrentLine );
  }

/*------------------------------------------------------------\
|                                                             |
|                    Gsb Read Segment Name                    |
|                                                             |
\------------------------------------------------------------*/

 void GsbReadSegmentName()

 {
   char  Layer;
   char  Field;
   char  LayerCount;
   char  EndTable;
   char *FirstWord; 
  
   EndTable   = 0;
   LayerCount = 0;

   while ( ( EndTable   != 1             ) &&
           ( LayerCount <= MBK_MAX_LAYER ) )
   {
     GsbGetLine( GsbBuffer );

     FirstWord  = GsbGetFirstWord( GsbBuffer, 1, 1 );
     
     if ( FirstWord == EndTableKeyword )
     {
       EndTable = 1;
     }
     else
     if ( LayerCount < MBK_MAX_LAYER )
     {
       Layer     = GsbGetStringValue( FirstWord );

       for ( Field = 0; Field < 3; Field++ )
       {
         FirstWord = GsbGetNextWord( 0, 0 );

         if ( FirstWord == EndRecordKeyword )
         {
           GsbError( MISSING_VALUE, (char *)NULL, GsbCurrentLine );
         }
         else
         {
           GRAAL_SEGMENT_NAME_TABLE [ Layer ][ Field ] = FirstWord;
         }
       }

       FirstWord = GsbGetNextWord( 0, 1 );
 
       if ( FirstWord != EndRecordKeyword )
       {
         GsbError( TOO_MANY_WORDS, FirstWord, GsbCurrentLine );
       }
     }
 
     LayerCount = LayerCount + 1;
   }

   if ( EndTable == 0 )
   {
     GsbError( LINE_EXPECTED, EndTableKeyword, GsbCurrentLine);
   }
 }

/*------------------------------------------------------------\
|                                                             |
|                    Gsb Read Connector Name                  |
|                                                             |
\------------------------------------------------------------*/

 void GsbReadConnectorName()

 {
   char  Layer;
   char  Field;
   char  LayerCount;
   char  EndTable;
   char *FirstWord; 
  
   EndTable   = 0;
   LayerCount = 0;

   while ( ( EndTable   != 1             ) &&
           ( LayerCount <= MBK_MAX_LAYER ) )
   {
     GsbGetLine( GsbBuffer );

     FirstWord  = GsbGetFirstWord( GsbBuffer, 1, 1 );
     
     if ( FirstWord == EndTableKeyword )
     {
       EndTable = 1;
     }
     else
     if ( LayerCount < MBK_MAX_LAYER )
     {
       Layer     = GsbGetStringValue( FirstWord );

       for ( Field = 0; Field < 3; Field++ )
       {
         FirstWord = GsbGetNextWord( 0, 0 );

         if ( FirstWord == EndRecordKeyword )
         {
           GsbError( MISSING_VALUE, (char *)NULL, GsbCurrentLine );
         }
         else
         {
           GRAAL_CONNECTOR_NAME_TABLE [ Layer ][ Field ] = FirstWord;
         }
       }

       FirstWord = GsbGetNextWord( 0, 1 );
 
       if ( FirstWord != EndRecordKeyword )
       {
         GsbError( TOO_MANY_WORDS, FirstWord, GsbCurrentLine );
       }
     }
 
     LayerCount = LayerCount + 1;
   }

   if ( EndTable == 0 )
   {
     GsbError( LINE_EXPECTED, EndTableKeyword, GsbCurrentLine);
   }
 }

/*------------------------------------------------------------\
|                                                             |
|                    Gsb Read Segment Value                   |
|                                                             |
\------------------------------------------------------------*/

 void GsbReadSegmentValue()

 {
   char  Layer;
   char  Field;
   char  LayerCount;
   char  EndTable;
   char *FirstWord; 
  
   EndTable   = 0;
   LayerCount = 0;

   while ( ( EndTable   != 1             ) &&
           ( LayerCount <= MBK_MAX_LAYER ) )
   {
     GsbGetLine( GsbBuffer );

     FirstWord  = GsbGetFirstWord( GsbBuffer, 1, 1 );
     
     if ( FirstWord == EndTableKeyword )
     {
       EndTable = 1;
     }
     else
     if ( LayerCount < MBK_MAX_LAYER )
     {
       Layer     = GsbGetStringValue( FirstWord );

       for ( Field = 0; Field < 2; Field++ ) 
       {
         FirstWord = GsbGetNextWord( 0, 0 );

         if ( FirstWord == EndRecordKeyword )
         {
           GsbError( MISSING_VALUE, (char *)NULL, GsbCurrentLine );
         }
         else
         {
           GRAAL_SEGMENT_VALUE_TABLE [ Layer ][ Field ] = GsbGetStringValue( FirstWord );
         }
       }

       FirstWord = GsbGetNextWord( 0, 1 );
 
       if ( FirstWord != EndRecordKeyword )
       {
         GsbError( TOO_MANY_WORDS, FirstWord, GsbCurrentLine );
       }
     }
 
     LayerCount = LayerCount + 1;
   }

   if ( EndTable == 0 )
   {
     GsbError( LINE_EXPECTED, EndTableKeyword, GsbCurrentLine);
   }
 }

/*------------------------------------------------------------\
|                                                             |
|                    Gsb Read Reference Name                  |
|                                                             |
\------------------------------------------------------------*/

 void GsbReadReferenceName()

 {
   char  Layer;
   char  Field;
   char  LayerCount;
   char  EndTable;
   char *FirstWord; 
  
   EndTable   = 0;
   LayerCount = 0;

   while ( ( EndTable   != 1                 ) &&
           ( LayerCount <= MBK_MAX_REFERENCE ) )
   {
     GsbGetLine( GsbBuffer );

     FirstWord  = GsbGetFirstWord( GsbBuffer, 1, 1 );
     
     if ( FirstWord == EndTableKeyword )
     {
       EndTable = 1;
     }
     else
     if ( LayerCount < MBK_MAX_REFERENCE )
     {
       Layer     = GsbGetStringValue( FirstWord );

       for ( Field = 0; Field < 3; Field++ ) 
       {
         FirstWord = GsbGetNextWord( 0, 0 );

         if ( FirstWord == EndRecordKeyword )
         {
           GsbError( MISSING_VALUE, (char *)NULL, GsbCurrentLine );
         }
         else
         {
           GRAAL_REFERENCE_NAME_TABLE [ Layer ][ Field ] = FirstWord;
         }
       }
 
       FirstWord = GsbGetNextWord( 0, 1 );
 
       if ( FirstWord != EndRecordKeyword )
       {
         GsbError( TOO_MANY_WORDS, FirstWord, GsbCurrentLine );
       }
     }
 
     LayerCount = LayerCount + 1;
   }

   if ( EndTable == 0 )
   {
     GsbError( LINE_EXPECTED, EndTableKeyword, GsbCurrentLine);
   }
 }

/*------------------------------------------------------------\
|                                                             |
|                      Gsb Read Orient Name                   |
|                                                             |
\------------------------------------------------------------*/

 void GsbReadOrientName()

 {
   char  Layer;
   char  Field;
   char  LayerCount;
   char  EndTable;
   char *FirstWord; 
  
   EndTable   = 0;
   LayerCount = 0;

   while ( ( EndTable   != 1              ) &&
           ( LayerCount <= MBK_MAX_ORIENT ) )
   {
     GsbGetLine( GsbBuffer );

     FirstWord  = GsbGetFirstWord( GsbBuffer, 1, 1 );
     
     if ( FirstWord == EndTableKeyword )
     {
       EndTable = 1;
     }
     else
     if ( LayerCount < MBK_MAX_ORIENT )
     {
       Layer     = GsbGetStringValue( FirstWord );

       for ( Field = 0; Field < 3; Field++ ) 
       {
         FirstWord = GsbGetNextWord( 0, 0 );

         if ( FirstWord == EndRecordKeyword )
         {
           GsbError( MISSING_VALUE, (char *)NULL, GsbCurrentLine );
         }
         else
         {
           GRAAL_ORIENT_NAME_TABLE [ Layer ][ Field ] = FirstWord;
         }
       }
 
       FirstWord = GsbGetNextWord( 0, 1 );
 
       if ( FirstWord != EndRecordKeyword )
       {
         GsbError( TOO_MANY_WORDS, FirstWord, GsbCurrentLine );
       }
     }
 
     LayerCount = LayerCount + 1;
   }

   if ( EndTable == 0 )
   {
     GsbError( LINE_EXPECTED, EndTableKeyword, GsbCurrentLine);
   }
 }

/*------------------------------------------------------------\
|                                                             |
|                      Gsb Read Symmetry Name                 |
|                                                             |
\------------------------------------------------------------*/

 void GsbReadSymmetryName()

 {
   char  Layer;
   char  Field;
   char  LayerCount;
   char  EndTable;
   char *FirstWord; 
  
   EndTable   = 0;
   LayerCount = 0;

   while ( ( EndTable   != 1                ) &&
           ( LayerCount <= MBK_MAX_SYMMETRY ) )
   {
     GsbGetLine( GsbBuffer );

     FirstWord  = GsbGetFirstWord( GsbBuffer, 1, 1 );
     
     if ( FirstWord == EndTableKeyword )
     {
       EndTable = 1;
     }
     else
     if ( LayerCount < MBK_MAX_SYMMETRY )
     {
       Layer     = GsbGetStringValue( FirstWord );

       for ( Field = 0; Field < 3; Field++ ) 
       {
         FirstWord = GsbGetNextWord( 0, 0 );

         if ( FirstWord == EndRecordKeyword )
         {
           GsbError( MISSING_VALUE, (char *)NULL, GsbCurrentLine );
         }
         else
         {
           GRAAL_SYMMETRY_NAME_TABLE [ Layer ][ Field ] = FirstWord;
         }
       }
 
       FirstWord = GsbGetNextWord( 0, 1 );
 
       if ( FirstWord != EndRecordKeyword )
       {
         GsbError( TOO_MANY_WORDS, FirstWord, GsbCurrentLine );
       }
     }
 
     LayerCount = LayerCount + 1;
   }

   if ( EndTable == 0 )
   {
     GsbError( LINE_EXPECTED, EndTableKeyword, GsbCurrentLine);
   }
 }

/*------------------------------------------------------------\
|                                                             |
|                    Gsb Read Via Name                        |
|                                                             |
\------------------------------------------------------------*/

 void GsbReadViaName()

 {
   char  Layer;
   char  LayerCount;
   char  EndTable;
   char  Field;
   char *FirstWord; 
  
   EndTable   = 0;
   LayerCount = 0;

   while ( ( EndTable   != 1           ) &&
           ( LayerCount <= MBK_MAX_VIA ) )
   {
     GsbGetLine( GsbBuffer );

     FirstWord  = GsbGetFirstWord( GsbBuffer, 1, 1 );
     
     if ( FirstWord == EndTableKeyword )
     {
       EndTable = 1;
     }
     else
     if ( LayerCount < MBK_MAX_VIA )
     {
       Layer     = GsbGetStringValue( FirstWord );

       for ( Field = 0; Field < 3; Field++ )
       {
         FirstWord = GsbGetNextWord( 1, 0 );

         if ( FirstWord == EndRecordKeyword )
         {
           GsbError( MISSING_VALUE, (char *)NULL, GsbCurrentLine );
         }
         else
         {
           GRAAL_VIA_NAME_TABLE [ Layer ][ Field ] = FirstWord;
         }
       }
    
       FirstWord = GsbGetNextWord( 0, 1 );
 
       if ( FirstWord != EndRecordKeyword )
       {
         GsbError( TOO_MANY_WORDS, FirstWord, GsbCurrentLine );
       }
     }
 
     LayerCount = LayerCount + 1;
   }

   if ( EndTable == 0 )
   {
     GsbError( LINE_EXPECTED, EndTableKeyword, GsbCurrentLine);
   }
 }

/*------------------------------------------------------------\
|                                                             |
|                    Gsb Read Rds Layer Name                  |
|                                                             |
\------------------------------------------------------------*/

 void GsbReadRdsLayerName()

 {
   char  Layer;
   char  LayerCount;
   char  EndTable;
   char  Field;
   char *FirstWord; 
  
   EndTable   = 0;
   LayerCount = 0;

   while ( ( EndTable   != 1             ) &&
           ( LayerCount <= RDS_MAX_LAYER ) )
   {
     GsbGetLine( GsbBuffer );

     FirstWord  = GsbGetFirstWord( GsbBuffer, 1, 1 );
     
     if ( FirstWord == EndTableKeyword )
     {
       EndTable = 1;
     }
     else
     if ( LayerCount < RDS_MAX_LAYER )
     {
       Layer     = GsbGetStringValue( FirstWord );

       for ( Field = 0; Field < 3; Field++ )
       {
         FirstWord = GsbGetNextWord( 1, 0 );

         if ( FirstWord == EndRecordKeyword )
         {
           GsbError( MISSING_VALUE, (char *)NULL, GsbCurrentLine );
         }
         else
         {
           GRAAL_RDS_LAYER_NAME_TABLE [ Layer ][ Field ] = FirstWord;
         }
       }
    
       FirstWord = GsbGetNextWord( 0, 1 );
 
       if ( FirstWord != EndRecordKeyword )
       {
         GsbError( TOO_MANY_WORDS, FirstWord, GsbCurrentLine );
       }
     }
 
     LayerCount = LayerCount + 1;
   }
 }
  
/*------------------------------------------------------------\
|                                                             |
|                      Gsb Read Parameters                    |
|                                                             |
\------------------------------------------------------------*/

  void GsbReadParam()

  {
    char *FirstWord;
    char *SecondWord;
    long  Continue;
  
    Continue = 0;

    while ( Continue != GSB_ALL_DEFINED_MASK )  
    {
      GsbGetLine( GsbBuffer );

      FirstWord = GsbGetFirstWord( GsbBuffer, 0, 1);

      if ( FirstWord == DefineKeyword ) 
      {
        FirstWord = GsbGetNextWord( 1, 1 );

        if (! FirstWord )
        {
          GsbError( MISSING_NAME, DefineKeyword, GsbCurrentLine );
        }

        SecondWord = GsbGetNextWord(1);

        if (! SecondWord ) 
        {
          GsbError( MISSING_VALUE, SecondWord );
        }

        if ( FirstWord == PeekBoundKeyword )
        {
          GRAAL_PEEK_BOUND = GsbGetStringValue( SecondWord );

          Continue |= GSB_PEEK_BOUND_MASK;
        }
        else
        if ( FirstWord == LowerGridStepKeyword )
        {
          GRAAL_LOWER_GRID_STEP = GsbGetStringFloat( SecondWord );

          Continue |= GSB_LOWER_GRID_STEP_MASK;
        }
        else
        if ( FirstWord == LowerFigureStepKeyword )
        {
          GRAAL_LOWER_FIGURE_STEP = GsbGetStringFloat( SecondWord );

          Continue |= GSB_LOWER_FIGURE_STEP_MASK;
        }
        else
        if ( FirstWord == LowerInstanceStepKeyword )
        {
          GRAAL_LOWER_INSTANCE_STEP = GsbGetStringFloat( SecondWord );

          Continue |= GSB_LOWER_INSTANCE_STEP_MASK;
        }
        else
        if ( FirstWord == LowerSegmentStepKeyword )
        {
          GRAAL_LOWER_SEGMENT_STEP = GsbGetStringFloat( SecondWord );

          Continue |= GSB_LOWER_SEGMENT_STEP_MASK;
        }
        else
        if ( FirstWord == LowerConnectorStepKeyword )
        {
          GRAAL_LOWER_CONNECTOR_STEP = GsbGetStringFloat( SecondWord );

          Continue |= GSB_LOWER_CONNECTOR_STEP_MASK;
        }
        else
        if ( FirstWord == LowerReferenceStepKeyword )
        {
          GRAAL_LOWER_REFERENCE_STEP = GsbGetStringFloat( SecondWord );

          Continue |= GSB_LOWER_REFERENCE_STEP_MASK;
        }
      }
      else 
      if ( FirstWord == TableKeyword )
      {
        if (!( FirstWord = GsbGetNextWord(1, 1)))
        {
          GsbError( MISSING_NAME, TableKeyword );
        }

        if ( FirstWord == ConnectorNameKeyword )
        {
          GsbReadConnectorName();

          Continue |= GSB_CONNECTOR_NAME_MASK;
        }
        else
        if ( FirstWord == SegmentNameKeyword )
        {
          GsbReadSegmentName();

          Continue |= GSB_SEGMENT_NAME_MASK;
        }
        else
        if ( FirstWord == SegmentValueKeyword )
        {
          GsbReadSegmentValue();

          Continue |= GSB_SEGMENT_VALUE_MASK;
        }
        else
        if ( FirstWord == ViaNameKeyword )
        {
          GsbReadViaName();

          Continue |= GSB_VIA_NAME_MASK;
        } 
        else
        if ( FirstWord == ReferenceNameKeyword )
        {
          GsbReadReferenceName();

          Continue |= GSB_REFERENCE_NAME_MASK;
        }
        else
        if ( FirstWord == OrientNameKeyword )
        {
          GsbReadOrientName();
 
          Continue |= GSB_ORIENT_NAME_MASK;
        }
        else
        if ( FirstWord == SymmetryNameKeyword )
        {
          GsbReadSymmetryName();
 
          Continue |= GSB_SYMMETRY_NAME_MASK;
        }
        else
        if ( FirstWord == RdsLayerNameKeyword )
        {
          GsbReadRdsLayerName();
 
          Continue |= GSB_RDS_LAYER_NAME_MASK;
        }
        else
        {
          GsbError( UNKNOWN_TABLE, FirstWord, GsbCurrentLine );
        }
      } 
      else
      { 
        GsbError( SYNTAX_ERROR, FirstWord, GsbCurrentLine );
      } 
    }       
  }

/*------------------------------------------------------------\
|                                                             |
|                      Gsb Load Parameters                    |
|                                                             |
\------------------------------------------------------------*/

  void GraalLoadParameters()

  {
    char  Layer;
    char *FileName;
    
    FileName = getenv( GRAAL_TECHNO_NAME );

    if ( FileName == (char *)NULL )
    {
      FileName = GraalDefaultTechnoName;
    }

    if ( ! KeywordDefined )
    {
      DefineKeyword             = namealloc( DEFINE_KEYWORD               );
      TableKeyword              = namealloc( TABLE_KEYWORD                );
      EndTableKeyword           = namealloc( END_TABLE_KEYWORD            );
      EndRecordKeyword          = namealloc( END_RECORD_KEYWORD           );
      PeekBoundKeyword          = namealloc( PEEK_BOUND_KEYWORD           );
      LowerGridStepKeyword      = namealloc( LOWER_GRID_STEP_KEYWORD      );
      LowerFigureStepKeyword    = namealloc( LOWER_FIGURE_STEP_KEYWORD    );
      LowerInstanceStepKeyword  = namealloc( LOWER_INSTANCE_STEP_KEYWORD  );
      LowerReferenceStepKeyword = namealloc( LOWER_REFERENCE_STEP_KEYWORD );
      LowerSegmentStepKeyword   = namealloc( LOWER_SEGMENT_STEP_KEYWORD   );
      LowerConnectorStepKeyword = namealloc( LOWER_CONNECTOR_STEP_KEYWORD );
      SegmentNameKeyword        = namealloc( SEGMENT_NAME_KEYWORD         );
      ConnectorNameKeyword      = namealloc( CONNECTOR_NAME_KEYWORD       );
      SegmentValueKeyword       = namealloc( SEGMENT_VALUE_KEYWORD        );
      ViaNameKeyword            = namealloc( VIA_NAME_KEYWORD             );
      ReferenceNameKeyword      = namealloc( REFERENCE_NAME_KEYWORD       );
      OrientNameKeyword         = namealloc( ORIENT_NAME_KEYWORD          );
      SymmetryNameKeyword       = namealloc( SYMMETRY_NAME_KEYWORD        );
      RdsLayerNameKeyword       = namealloc( RDS_LAYER_NAME_KEYWORD       );

      KeywordDefined = 1;
    }

    for ( Layer = 0; Layer < MBK_MAX_LAYER; Layer++ )
    {
      GRAAL_CONNECTOR_NAME_TABLE[ Layer ][0] = GRAAL_NOT_DEFINE;
      GRAAL_CONNECTOR_NAME_TABLE[ Layer ][1] = (char *)NULL;
      GRAAL_CONNECTOR_NAME_TABLE[ Layer ][2] = (char *)NULL;

      GRAAL_SEGMENT_NAME_TABLE[ Layer ][0] = GRAAL_NOT_DEFINE;
      GRAAL_SEGMENT_NAME_TABLE[ Layer ][1] = (char *)NULL;
      GRAAL_SEGMENT_NAME_TABLE[ Layer ][2] = (char *)NULL;

      GRAAL_SEGMENT_VALUE_TABLE[ Layer ][0] = 0;
      GRAAL_SEGMENT_VALUE_TABLE[ Layer ][1] = 0;
    }

    for ( Layer = 0; Layer < MBK_MAX_VIA; Layer++ )
    {
      GRAAL_VIA_NAME_TABLE[ Layer ][0]  = GRAAL_NOT_DEFINE;
      GRAAL_VIA_NAME_TABLE[ Layer ][1]  = (char *)NULL;
      GRAAL_VIA_NAME_TABLE[ Layer ][2]  = (char *)NULL;
    }

    for ( Layer = 0; Layer < MBK_MAX_REFERENCE; Layer++ )
    {
      GRAAL_REFERENCE_NAME_TABLE[ Layer ][0] = GRAAL_NOT_DEFINE;
      GRAAL_REFERENCE_NAME_TABLE[ Layer ][1] = (char *)NULL;
      GRAAL_REFERENCE_NAME_TABLE[ Layer ][2] = (char *)NULL;
    }

    for ( Layer = 0; Layer < RDS_MAX_LAYER; Layer++ )
    {
      GRAAL_RDS_LAYER_NAME_TABLE[ Layer ][0] = GRAAL_NOT_DEFINE;
      GRAAL_RDS_LAYER_NAME_TABLE[ Layer ][1] = (char *)NULL;
      GRAAL_RDS_LAYER_NAME_TABLE[ Layer ][2] = (char *)NULL;
    }
    
    for ( Layer = 0; Layer < MBK_MAX_SYMMETRY; Layer++ )
    {
      GRAAL_SYMMETRY_NAME_TABLE[ Layer ][0] = GRAAL_NOT_DEFINE;
      GRAAL_SYMMETRY_NAME_TABLE[ Layer ][1] = (char *)NULL;
      GRAAL_SYMMETRY_NAME_TABLE[ Layer ][2] = (char *)NULL;
    }

    for ( Layer = 0; Layer < MBK_MAX_ORIENT; Layer++ )
    {
      GRAAL_ORIENT_NAME_TABLE[ Layer ][0] = GRAAL_NOT_DEFINE;
      GRAAL_ORIENT_NAME_TABLE[ Layer ][1] = (char *)NULL;
      GRAAL_ORIENT_NAME_TABLE[ Layer ][2] = (char *)NULL;
    }

    GRAAL_PEEK_BOUND            = 0;
    GRAAL_LOWER_GRID_STEP       = 0.0;
    GRAAL_LOWER_FIGURE_STEP     = 0.0;
    GRAAL_LOWER_INSTANCE_STEP   = 0.0;
    GRAAL_LOWER_CONNECTOR_STEP  = 0.0;
    GRAAL_LOWER_SEGMENT_STEP    = 0.0;
    GRAAL_LOWER_REFERENCE_STEP  = 0.0;

    if ( !( GsbFile = fopen( FileName, "r")))

      GsbError( OPEN_FILE, FileName, 0);

    GsbReadParam();

    fclose( GsbFile );
  }

/*------------------------------------------------------------\
|                                                             |
|                      Gsb View Parameters                    |
|                                                             |
\------------------------------------------------------------*/

  void GraalViewParameters()

  {
    char Layer;

    fprintf( stdout, "\nPEEK_BOUND DEFINE %d\n", GRAAL_PEEK_BOUND );

    fprintf( stdout, "\nSEGMENT TABLE\n" );

    for ( Layer = 0; Layer < MBK_MAX_LAYER; Layer++ )
    {
      fprintf( stdout, "\nLayer:%d %s %s %s %d %d", 
               Layer,
               GRAAL_SEGMENT_NAME_TABLE[ Layer ][0],
               GRAAL_SEGMENT_NAME_TABLE[ Layer ][1],
               GRAAL_SEGMENT_NAME_TABLE[ Layer ][2],
               GRAAL_SEGMENT_VALUE_TABLE[ Layer ][0],
               GRAAL_SEGMENT_VALUE_TABLE[ Layer ][1] );
    }

    fprintf( stdout, "\n\nEND\n" );

    fprintf( stdout, "\nCONNECTOR TABLE\n" );

    for ( Layer = 0; Layer < MBK_MAX_LAYER; Layer++ )
    {
      fprintf( stdout, "\nLayer:%d %s %s %s",
               Layer,
               GRAAL_CONNECTOR_NAME_TABLE[ Layer ][0],
               GRAAL_CONNECTOR_NAME_TABLE[ Layer ][1],
               GRAAL_CONNECTOR_NAME_TABLE[ Layer ][2] );
    }

    fprintf( stdout, "\n\nEND\n" );

    fprintf( stdout, "\nVIA TABLE\n" );

    for ( Layer = 0; Layer < MBK_MAX_VIA; Layer++ )
    {
      fprintf( stdout, "\nVia:%d %s %s %s", 
               Layer,
               GRAAL_VIA_NAME_TABLE[ Layer ][0],
               GRAAL_VIA_NAME_TABLE[ Layer ][1],
               GRAAL_VIA_NAME_TABLE[ Layer ][2] );
    }

    fprintf( stdout, "\n\nEND\n" );

    fprintf( stdout, "\nREFERENCE TABLE\n" );

    for ( Layer = 0; Layer < MBK_MAX_REFERENCE; Layer++ )
    {
      fprintf( stdout, "\nReference:%d %s %s %s", 
               Layer, 
               GRAAL_REFERENCE_NAME_TABLE[ Layer ][0],
               GRAAL_REFERENCE_NAME_TABLE[ Layer ][1],
               GRAAL_REFERENCE_NAME_TABLE[ Layer ][2] );
    }

    fprintf( stdout, "\nORIENT TABLE\n" );

    for ( Layer = 0; Layer < MBK_MAX_ORIENT; Layer++ )
    {
      fprintf( stdout, "\nSymmetry:%d %s %s %s", 
               Layer, 
               GRAAL_ORIENT_NAME_TABLE[ Layer ][0],
               GRAAL_ORIENT_NAME_TABLE[ Layer ][1],
               GRAAL_ORIENT_NAME_TABLE[ Layer ][2] );
    }

    fprintf( stdout, "\nSYMMETRY TABLE\n" );

    for ( Layer = 0; Layer < MBK_MAX_SYMMETRY; Layer++ )
    {
      fprintf( stdout, "\nReference:%d %s %s %s", 
               Layer, 
               GRAAL_SYMMETRY_NAME_TABLE[ Layer ][0],
               GRAAL_SYMMETRY_NAME_TABLE[ Layer ][1],
               GRAAL_SYMMETRY_NAME_TABLE[ Layer ][2] );
    }

    fprintf( stdout, "\n\nEND\n" );

    fprintf( stdout, "\nRDS_LAYER TABLE\n" );

    for ( Layer = 0; Layer < RDS_MAX_LAYER; Layer++ )
    {
      fprintf( stdout, "\nLayer:%d %s %s %s", 
               Layer, 
               GRAAL_RDS_LAYER_NAME_TABLE[ Layer ][0],
               GRAAL_RDS_LAYER_NAME_TABLE[ Layer ][1],
               GRAAL_RDS_LAYER_NAME_TABLE[ Layer ][2] );
    }

    fprintf( stdout, "\n\nEND\n" );
  }
