/*------------------------------------------------------------\
|                                                             |
| Tool    :                     DRUC                          |
|                                                             |
| File    :                  DRUCOMPI.C                       |
|                                                             |
| Authors :                Patrick Renaud                     |
|                                                             |
| Date    :                   11/01/94                        |
|                                                             |
\------------------------------------------------------------*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <malloc.h>
#include MPH_H
#include MUT_H
#include RDS_H
#include RUT_H
#include RTL_H
#include RWI_H
#include RFM_H
#include RPR_H
#include "drucompi.yac.tab.h"
#include "drucutil.h"
#include "vmctools.h"
#include "drucompi.h"
/*------------------------------------------------------------\
|                                                             |
|                  DRUCOMPI  variables                        |
|                                                             |
\------------------------------------------------------------*/
DrucTypeStructDefine    DrucStructDefine;
DrucTypeStructRegle     DrucStructRegle;

int                     CurrentIndexDrucLayer;
long                    DrucCtmMax;

FILE                   *TmpFileAssembler;
char                    DRUC_OUTPUT_NAME[256];
char                    DRUC_TMP_OUTPUT_NAME[256];

/*------------------------------------------------------------\
|                                                             |
|                  DRUCOMPI  Fonctions                        |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                  Druc yyerror                               |
|                                                             |
\------------------------------------------------------------*/
void yyerror(s)
  char *s;
{
  fprintf (stdout,"\nErreur Langage ligne %d : %s\n",yylineno,s);
  exit(1);
}
/*------------------------------------------------------------\
|                                                             |
|                  DrucInitCompiler                           |
|                                                             |
| Ouvre le fichier de destination du code assembleur de DRUC  |
| Initialise la structure DrucStructRdsLayer                  |
| Initialise la structure DrucStructDefine                    |
| Initialise la structure DrucStructRegle                     |
\------------------------------------------------------------*/
void DrucInitCompiler ()
{
  int      TmpIndexMesure;
  int      IndexLayer;
  boolean  FlagBegin;
  char     DrucFileBuffer [ DRUC_MAX_FILE_BUFFER+1 ];
  CurrentIndexDrucLayer = DRUC_UNDEFINED_LAYER;
  DrucCheckSumm         = DRUC_UNDEFINED_CHECKSUMM;
  DrucCtmMax            = DRUC_UNDEFINED_CTM;

  for ( IndexLayer  = 0;
        IndexLayer  < RDS_MAX_LAYER;
        IndexLayer ++
      )
    {
      DrucStructRdsLayer [ IndexLayer ].RDS_INDEX = DRUC_UNDEFINED_LAYER;
      DrucStructRdsLayer [ IndexLayer ].WIDTH     = DRUC_UNDEFINED_WIDTH;
      DrucStructRdsLayer [ IndexLayer ].CTM       = DRUC_UNDEFINED_CTM;
    }

  DrucStructDefine.LAYER_DEST        = DRUC_UNDEFINED_LAYER;
  DrucStructDefine.OP_COMPOSE        = DRUC_UNDEFINED_OP_COMPOSE;
  DrucStructDefine.LAYER_1           = DRUC_UNDEFINED_LAYER;
  DrucStructDefine.LAYER_2           = DRUC_UNDEFINED_LAYER;
  DrucStructDefine.USER_LAYER_0      = DRUC_UNDEFINED_LAYER;
  DrucStructDefine.USER_LAYER_1      = DRUC_UNDEFINED_LAYER;
  DrucStructDefine.USER_LAYER_2      = DRUC_UNDEFINED_LAYER;
  DrucStructDefine.USER_LAYER_NAME_0 = (char *)NULL;
  DrucStructDefine.USER_LAYER_NAME_1 = (char *)NULL;
  DrucStructDefine.USER_LAYER_NAME_2 = (char *)NULL;

  DrucStructRegle.LIST_REGLE_NUM     = (DataList *)NULL;
  DrucStructRegle.INSTRUCTION        = DRUC_UNDEFINED_INSTRUCTION;
  DrucStructRegle.LAYER_1            = DRUC_UNDEFINED_LAYER;
  DrucStructRegle.LAYER_2            = DRUC_UNDEFINED_LAYER;
  for ( TmpIndexMesure  = 0;
        TmpIndexMesure  < DRUC_MAX_MESURES;
        TmpIndexMesure ++
      )
  {
    DrucStructRegle.RELATION   [TmpIndexMesure ] = DRUC_UNDEFINED_RELATION;
    DrucStructRegle.REGLE_NUM  [TmpIndexMesure ] = DRUC_UNDEFINED_REGLE;
    DrucStructRegle.MESURE     [TmpIndexMesure ] = DRUC_UNDEFINED_MESURE;
    DrucStructRegle.OP_COMPARE [TmpIndexMesure ] = DRUC_UNDEFINED_OPERATEUR;
    DrucStructRegle.VALEUR     [TmpIndexMesure ] = DRUC_UNDEFINED_VALEUR;
  }
  DrucFileAssembler = fopen ( DRUC_OUTPUT_NAME ,"r");
  if ( DrucFileAssembler == (FILE *)NULL )
  {
    DRUC_EXIT ( DRUC_ERROR_OUT_FILE );
  }
  FlagBegin        = DRUC_FALSE;
  TmpFileAssembler = fopen ( DRUC_TMP_OUTPUT_NAME ,"w");
  if ( TmpFileAssembler == (FILE *) NULL )
  {
    DRUC_EXIT ( DRUC_ERROR_OUT_FILE );
  }
  /*\
   * recherche du debut des regles en assembleur dans le fichier
  \*/
  IndexLayer = 0;
  while ( FlagBegin != DRUC_TRUE )
  {
    if ( fgets( DrucFileBuffer,
                DRUC_MAX_FILE_BUFFER,
                DrucFileAssembler
              )
         != (char *)NULL
       )
    {
      IndexLayer ++;
      fputs( DrucFileBuffer , TmpFileAssembler );
      if ( strstr( DrucFileBuffer, DRUC_DRC_RULES ) != (char *)NULL )
      {
        FlagBegin = DRUC_TRUE;
      }
    }
    /*\
     * ou remise au debut du code assembleur
    \*/
    else
    {
      fputs( DRUC_DRC_RULES, TmpFileAssembler );
      fputs( "\n", TmpFileAssembler );
      FlagBegin = DRUC_TRUE;
    }
  }
  fclose( DrucFileAssembler );
}
/*------------------------------------------------------------\
|                                                             |
|                  DrucCloseCompiler                          |
|                                                             |
| Ferme le fichier de destination du code assembleur de DRUC  |
\------------------------------------------------------------*/
void DrucCloseCompiler ()
{
  DrucComputeCheckSumm( DRUC_ASM_BEGIN_CHECKSUMM );
  if ( fclose( TmpFileAssembler ) == EOF )
  {
    DRUC_EXIT ( DRUC_ERROR_CLOSE_DRC_FILE );
  }
}
/*------------------------------------------------------------\
|                                                             |
|                  DrucEndRulesCompiler                       |
|                                                             |
| Ferme le fichier de destination du code assembleur de DRUC  |
\------------------------------------------------------------*/
void DrucEndRulesCompiler ()
{
  DrucComputeCheckSumm( DRUC_ASM_BEGIN_CHECKSUMM );
  fprintf( TmpFileAssembler,
           "%d %d %d\n%s\n",
           DRUC_ASM_BEGIN_CHECKSUMM,
           DrucCheckSumm,
           DRUC_ASM_END_CHECKSUMM,
           DRUC_END_DRC_RULES
         );
}
/*------------------------------------------------------------\
|                                                             |
|                  DrucInitRdsLayerName                       |
|                                                             |
| Trouve le Name dans la liste des layers RDS ou sort         |
| Range l'index associe dans DrucStructRdsLayer.RDS_INDEX     |
\------------------------------------------------------------*/
void DrucInitRdsLayerName (Name)
     char *Name;
{
  int IndexLayer = 0;

  CurrentIndexDrucLayer  = DRUC_UNDEFINED_LAYER;
  while( IndexLayer <= RDS_MAX_LAYER )
  {
    if ( strncmp ( RDS_LAYER_NAME[ IndexLayer ], 
                   Name ,
                   strlen (Name)
                 )
         == 0
       )
    {
      if ( DrucStructRdsLayer[ IndexLayer ].RDS_INDEX == DRUC_UNDEFINED_LAYER )
      {
        DrucStructRdsLayer[ IndexLayer ].RDS_INDEX = IndexLayer;
        CurrentIndexDrucLayer                      = IndexLayer;
        return;
      }
    }
    IndexLayer ++ ;
  }
  DRUC_EXIT( DRUC_ERROR_UNDEFINED_LAYER );
}
/*------------------------------------------------------------\
|                                                             |
|                  DrucInitRdsLayerDef                        |
|                                                             |
| Range la Value associe dans DrucStructRdsLayer.WIDTH        |
| dont l'index est dans CurrentIndexDrucLayer                 |
\------------------------------------------------------------*/
void DrucInitRdsLayerDef (Value)
     int Value;
{
  if ( CurrentIndexDrucLayer == DRUC_UNDEFINED_LAYER)
  {
    DRUC_EXIT( DRUC_ERROR_UNDEFINED_LAYER );
  }
DrucViewString ("DrucInitRdsLayerDef");
DrucViewNumber (Value);
  DrucStructRdsLayer[ CurrentIndexDrucLayer ].WIDTH = Value;
  CurrentIndexDrucLayer = DRUC_UNDEFINED_LAYER;
}
/*------------------------------------------------------------\
|                                                             |
|                  DrucStoreRdsLayer                          |
|                                                             |
| Ecrit dans le fichier *TmpFileAssembler, les layers         |
| contenus dans DrucStructRdsLayer[] avec leur valeur min     |
| pour la verification des regles et l'unification            |
| Stocke le checksumm des ecritures dans DrucCheckSumm        |
\------------------------------------------------------------*/
void DrucStoreRdsLayer ()
{
  register int IndexLayer;

  fprintf( TmpFileAssembler,
           "%d ",
           DRUC_ASM_BEGIN_LAYER
         );
  DrucComputeCheckSumm( DRUC_ASM_BEGIN_LAYER );

  for( IndexLayer  = 0;
       IndexLayer != RDS_MAX_LAYER;
       IndexLayer ++
     )
  {
    if ((DrucStructRdsLayer[ IndexLayer ].RDS_INDEX != DRUC_UNDEFINED_LAYER ) &&
        (DrucStructRdsLayer[ IndexLayer ].CTM == DRUC_UNDEFINED_LAYER )
       )
    {
      DrucStructRdsLayer[ IndexLayer ].CTM = DrucCtmMax;
    } 
    fprintf( TmpFileAssembler,
             "%d %d %d ",
              DrucStructRdsLayer[ IndexLayer ].RDS_INDEX,
              DrucStructRdsLayer[ IndexLayer ].WIDTH,
              DrucStructRdsLayer[ IndexLayer ].CTM
           );
    DrucComputeCheckSumm( DrucStructRdsLayer[ IndexLayer ].RDS_INDEX );
    DrucComputeCheckSumm( (int)DrucStructRdsLayer[ IndexLayer ].WIDTH );
    DrucComputeCheckSumm( (int)DrucStructRdsLayer[ IndexLayer ].CTM );
  }
  fprintf( TmpFileAssembler,
           "%d\n",
           DRUC_ASM_END_LAYER
         );
  DrucComputeCheckSumm(DRUC_ASM_END_LAYER );
}
/*------------------------------------------------------------\
|                                                             |
|                  DrucInitDefineLayerDest                    |
|                                                             |
| Verifie que le Name n'est pas dans la liste des layers RDS  |
| ou sort                                                     |
| Verifie que le Name n'est pas dans la liste des layers      |
| user deja declares pour DRUC ou sort                        |
| Range le Name associe dans                                  |
|    DrucTypeStructDefine.USER_LAYER_NAME_i                   |
|     i est le premier LAYER_USER_NAME libre                  |
| Range le numero de layer RDS dans                           |
|    DrucTypeStructDefine.USER_LAYER_                         |
|     i est le premier LAYER_USER libre                       |
\------------------------------------------------------------*/
void DrucInitDefineLayerDest (Name)
     char *Name;
{
  int IndexLayer = 0;

  /*\
   *  Le nom existe dans la liste des layers RDS
  \*/
  while( IndexLayer < RDS_MAX_LAYER )
  {
    if ( strstr( RDS_LAYER_NAME[ IndexLayer ], Name ) != ( char *) NULL )
    {
      DRUC_EXIT( DRUC_ERROR_DEFINE_USER_LAYER);
    }
    IndexLayer ++ ;
  }
  /*\
   *  Le nom existe dans la liste des layers USER en usage
  \*/
  if ( DrucStructDefine.USER_LAYER_NAME_0 != (char *)NULL )
  {
    if ( strstr( DrucStructDefine.USER_LAYER_NAME_0, Name ) != (char *)NULL )
    {
      DRUC_EXIT( DRUC_ERROR_DEFINE_USER_LAYER);
    }
  }
  if ( DrucStructDefine.USER_LAYER_NAME_1 != (char *)NULL )
  {
    if ( strstr( DrucStructDefine.USER_LAYER_NAME_1, Name ) != (char *)NULL )
    {
      DRUC_EXIT( DRUC_ERROR_DEFINE_USER_LAYER);
    }
  }
  if ( DrucStructDefine.USER_LAYER_NAME_2 != (char *)NULL )
  {
    if ( strstr( DrucStructDefine.USER_LAYER_NAME_2, Name ) != (char *)NULL )
    {
      DRUC_EXIT( DRUC_ERROR_DEFINE_USER_LAYER);
    }
  }
  /*\
   *  Les layers USER ne sont pas tous en usage
  \*/
  if ( DrucStructDefine.USER_LAYER_NAME_0 != (char *)NULL )
  {
    if ( DrucStructDefine.USER_LAYER_NAME_1 != (char *)NULL )
    {
      if ( DrucStructDefine.USER_LAYER_NAME_2 != (char *)NULL )
      {
        DRUC_EXIT( DRUC_ERROR_DEFINE_USER_LAYER );
      }
      DrucStructDefine.LAYER_DEST        = DRUC_USER_LAYER_2;
      DrucStructDefine.USER_LAYER_2      = DRUC_USER_LAYER_2;
      DrucStructDefine.USER_LAYER_NAME_2 = (char *)malloc ( strlen ( Name ) +1 );
      strcpy ( DrucStructDefine.USER_LAYER_NAME_2 ,Name );
      return;
    }
    DrucStructDefine.LAYER_DEST        = DRUC_USER_LAYER_1;
    DrucStructDefine.USER_LAYER_1      = DRUC_USER_LAYER_1;
    DrucStructDefine.USER_LAYER_NAME_1 = (char *)malloc ( strlen ( Name ) +1 );
    strcpy ( DrucStructDefine.USER_LAYER_NAME_1 ,Name );
    return;
  }

  DrucStructDefine.LAYER_DEST        = DRUC_USER_LAYER_0;
  DrucStructDefine.USER_LAYER_0      = DRUC_USER_LAYER_0;
  DrucStructDefine.USER_LAYER_NAME_0 = (char *)malloc ( strlen ( Name ) +1 );
  strcpy ( DrucStructDefine.USER_LAYER_NAME_0 ,Name );
}
/*------------------------------------------------------------\
|                                                             |
|                  DrucStructDefineOpCompose                  |
|                                                             |
\------------------------------------------------------------*/
void DrucStructDefineOpCompose ( Operateur )
     int Operateur;
{
  DrucStructDefine.OP_COMPOSE = Operateur;
}
/*------------------------------------------------------------\
|                                                             |
|                  DrucInitDefineLayerA                       |
|                                                             |
| Verifie que le Name est dans la liste des layers RDS        |
| ou sort                                                     |
| Verifie que le layer correspondant est initialise           |
| ou sort                                                     |
| Range l'index associe dans                                  |
|    DrucTypeStructDefine.USER_LAYER_SOURCE_A                 |
\------------------------------------------------------------*/
void DrucInitDefineLayerA (Name)
     char *Name;
{
  int IndexLayer = 0;

  /*\
   *  Le nom existe dans la liste des layers RDS
  \*/
  while( IndexLayer < RDS_MAX_LAYER )
  {
    if ( strncmp ( RDS_LAYER_NAME[ IndexLayer ], 
                   Name , 
                   strlen (Name) 
                 ) 
         == 0
       )
    if ( DrucStructRdsLayer[ IndexLayer ].RDS_INDEX == IndexLayer 
       ) 
    {
      DrucStructRegle.LAYER_1  = DrucStructRdsLayer[ IndexLayer ].RDS_INDEX;
      DrucStructDefine.LAYER_1 = DrucStructRdsLayer[ IndexLayer ].RDS_INDEX;
      return;
    }
    IndexLayer ++ ;
  }
  /*\
   *  Le nom existe dans la liste des layers USER
  \*/
  if ( DrucStructDefine.USER_LAYER_NAME_0 != (char *)NULL )
  {
    if ( strstr( DrucStructDefine.USER_LAYER_NAME_0, Name ) != (char *)NULL )
    {
      DrucStructRegle.LAYER_1  = DRUC_USER_LAYER_0;
      DrucStructDefine.LAYER_1 = DRUC_USER_LAYER_0;
      return;
    }
  }
  if ( DrucStructDefine.USER_LAYER_NAME_1 != (char *)NULL )
  {
    if ( strstr( DrucStructDefine.USER_LAYER_NAME_1, Name ) != (char *)NULL )
    {
      DrucStructRegle.LAYER_1  = DRUC_USER_LAYER_1;
      DrucStructDefine.LAYER_1 = DRUC_USER_LAYER_1;
      return;
    }
  }
  if ( DrucStructDefine.USER_LAYER_NAME_2 != (char *)NULL )
  {
    if ( strstr( DrucStructDefine.USER_LAYER_NAME_2, Name ) !=
     (char *)NULL )
    {
      DrucStructRegle.LAYER_1  = DRUC_USER_LAYER_2;
      DrucStructDefine.LAYER_1 = DRUC_USER_LAYER_2;
      return;
    }
  }
  DRUC_EXIT( DRUC_ERROR_UNDEFINED_LAYER );
}
/*------------------------------------------------------------\
|                                                             |
|                  DrucInitDefineLayerB                       |
|                                                             |
| Verifie que le Name est dans la liste des layers RDS        |
| ou sort                                                     |
| Verifie que le layer correspondant est initialise           |
| ou sort                                                     |
| Range l'index associe dans                                  |
|    DrucTypeStructDefine.USER_LAYER_SOURCE_B                 |
\------------------------------------------------------------*/
void DrucInitDefineLayerB (Name)
     char *Name;
{
  int IndexLayer = 0;

  /*\
   *  Le nom existe dans la liste des layers RDS
  \*/
  while( IndexLayer < RDS_MAX_LAYER )
  {
    if ( strncmp ( RDS_LAYER_NAME[ IndexLayer ], 
                   Name , 
                   strlen (Name) 
                 ) 
         == 0
       )
    if ( DrucStructRdsLayer[ IndexLayer ].RDS_INDEX == IndexLayer 
       ) 
    {
      DrucStructRegle.LAYER_2  = DrucStructRdsLayer[ IndexLayer ].RDS_INDEX;
      DrucStructDefine.LAYER_2 = DrucStructRdsLayer[ IndexLayer ].RDS_INDEX;
      return;
    }
    IndexLayer ++ ;
  }
  /*\
   *  Le nom existe dans la liste des layers USER
  \*/
  if ( DrucStructDefine.USER_LAYER_NAME_0 != (char *)NULL )
  {
    if ( strstr( DrucStructDefine.USER_LAYER_NAME_0, Name ) != (char *)NULL )
    {
      DrucStructRegle.LAYER_2  = DRUC_USER_LAYER_0;
      DrucStructDefine.LAYER_2 = DRUC_USER_LAYER_0;
      return;
    }
  }
  if ( DrucStructDefine.USER_LAYER_NAME_1 != (char *)NULL )
  {
    if ( strstr( DrucStructDefine.USER_LAYER_NAME_1, Name ) != (char *)NULL )
    {
      DrucStructRegle.LAYER_2  = DRUC_USER_LAYER_1;
      DrucStructDefine.LAYER_2 = DRUC_USER_LAYER_1;
      return;
    }
  }
  if ( DrucStructDefine.USER_LAYER_NAME_2 != (char *)NULL )
  {
    if ( strstr( DrucStructDefine.USER_LAYER_NAME_2, Name ) !=
     (char *)NULL )
    {
      DrucStructRegle.LAYER_2  = DRUC_USER_LAYER_2;
      DrucStructDefine.LAYER_2 = DRUC_USER_LAYER_2;
      return;
    }
  }
  DRUC_EXIT( DRUC_ERROR_UNDEFINED_LAYER );
}
/*------------------------------------------------------------\
|                                                             |
|                  DrucStoreInstructionDefine                 |
|                                                             |
| Ecrit dans le fichier *TmpFileAssembler, l'instruction      |
| contenue dans DrucStructDefine avec ses valeurs             |
| Stocke le checksumm des ecritures dans DrucCheckSumm        |
| DrucStructDefine.USER_LAYER_NAME_0        n'est pas ecrit   |
| DrucStructDefine.USER_LAYER_NAME_1        n'est pas ecrit   |
| DrucStructDefine.USER_LAYER_NAME_2        n'est pas ecrit   |
| Seuls les numeros de layer associes sont ecrits             |
\------------------------------------------------------------*/
void DrucStoreInstructionDefine ()
{
  fprintf( TmpFileAssembler,
           "%d ",
           DRUC_ASM_BEGIN_DEFINE
         );
  DrucComputeCheckSumm( DRUC_ASM_BEGIN_DEFINE );

  fprintf( TmpFileAssembler,
           "%d %d %d %d ",
            DrucStructDefine.LAYER_DEST,
            DrucStructDefine.OP_COMPOSE,
            DrucStructDefine.LAYER_1,
            DrucStructDefine.LAYER_2
         );

  DrucComputeCheckSumm( DrucStructDefine.LAYER_DEST );
  DrucComputeCheckSumm( DrucStructDefine.OP_COMPOSE );
  DrucComputeCheckSumm( DrucStructDefine.LAYER_1 );
  DrucComputeCheckSumm( DrucStructDefine.LAYER_2 );

  fprintf( TmpFileAssembler,
           "%d\n",
           DRUC_ASM_END_DEFINE
         );
  DrucComputeCheckSumm( DRUC_ASM_END_DEFINE );

  DrucStructDefine.LAYER_DEST        = DRUC_UNDEFINED_LAYER;
  DrucStructDefine.OP_COMPOSE        = DRUC_UNDEFINED_OP_COMPOSE;
  DrucStructDefine.LAYER_1           = DRUC_UNDEFINED_LAYER;
  DrucStructDefine.LAYER_2           = DRUC_UNDEFINED_LAYER;
}
/*------------------------------------------------------------\
|                                                             |
|                  DrucInitUndefineUserLayer                  |
|                                                             |
| Trouve Name dans DrucStructDefine.USER_LAYER_i  ou sort     |
| Range son index dans DrucStructDefine.USER_LAYER_i          |
\------------------------------------------------------------*/
void DrucInitUndefineUserLayer (Name)
     char *Name;
{

  /*\
   *  Le nom existe dans la liste des layers USER en usage
  \*/
  if ( DrucStructDefine.USER_LAYER_NAME_0 != (char *)NULL )
  {
    if ( strstr( DrucStructDefine.USER_LAYER_NAME_0, Name ) != (char *)NULL )
    {
      DrucStructDefine.LAYER_DEST        = DRUC_USER_LAYER_0;
      DrucStructDefine.USER_LAYER_0      = DRUC_UNDEFINED_LAYER;
      free ( DrucStructDefine.USER_LAYER_NAME_0 );
      DrucStructDefine.USER_LAYER_NAME_0 = (char *)NULL;
      return;
    }
  }
  if ( DrucStructDefine.USER_LAYER_NAME_1 != (char *)NULL )
  {
    if ( strcmp( DrucStructDefine.USER_LAYER_NAME_1, Name ) == 0 )
    {
      DrucStructDefine.LAYER_DEST        = DRUC_USER_LAYER_1;
      DrucStructDefine.USER_LAYER_1      = DRUC_UNDEFINED_LAYER;
      free ( DrucStructDefine.USER_LAYER_NAME_1 );
      DrucStructDefine.USER_LAYER_NAME_1 = (char *)NULL;
      return;
    }
  }
  if ( DrucStructDefine.USER_LAYER_NAME_2 != (char *)NULL )
  {
    if ( strcmp( DrucStructDefine.USER_LAYER_NAME_2, Name ) == 0 )
    {
      DrucStructDefine.LAYER_DEST        = DRUC_USER_LAYER_2;
      DrucStructDefine.USER_LAYER_2      = DRUC_UNDEFINED_LAYER;
      free ( DrucStructDefine.USER_LAYER_NAME_2 );
      DrucStructDefine.USER_LAYER_NAME_2 = (char *)NULL;
      return;
    }
  }
  /*\
   *  Le Name n'existe pas dans la liste des layers user
  \*/
   DRUC_EXIT( DRUC_ERROR_UNDEFINED_LIYER );
}
/*------------------------------------------------------------\
|                                                             |
|                  DrucStoreInstructionUndefine               |
|                                                             |
| Ecrit dans le fichier *TmpFileAssembler, l'instruction      |
| contenue dans DrucStructDefine avec ses valeurs             |
| Stocke le checksumm des ecritures dans DrucCheckSumm        |
| Seuls le numero de layer user est ecrit                     |
\------------------------------------------------------------*/
void DrucStoreInstructionUndefine ()
{
  fprintf( TmpFileAssembler,
           "%d ",
           DRUC_ASM_BEGIN_UNDEFINE
         );
  DrucComputeCheckSumm( DRUC_ASM_BEGIN_UNDEFINE );

  fprintf( TmpFileAssembler,
           "%d ",
           DrucStructDefine.LAYER_DEST
         );
  DrucComputeCheckSumm( DrucStructDefine.LAYER_DEST );

  fprintf( TmpFileAssembler,
           "%d\n",
           DRUC_ASM_END_UNDEFINE
         );
  DrucComputeCheckSumm( DRUC_ASM_END_UNDEFINE );
  DrucStructDefine.LAYER_DEST = DRUC_UNDEFINED_LAYER;
}
/*------------------------------------------------------------\
|                                                             |
|                  DrucInitRegleNumero                        |
|                                                             |
\------------------------------------------------------------*/
void DrucInitRegleNumero ( Value,
                           DrucIndexMesure
                         )
     int Value;
     int DrucIndexMesure;
{
  DataList *TmpListReglNum;

  if ( DrucIndexMesure >= DRUC_MAX_MESURES )
  {
    DRUC_EXIT( DRUC_ERROR_MAX_OPERATOR );
  }
  for( TmpListReglNum  = DrucStructRegle.LIST_REGLE_NUM;
       TmpListReglNum != (DataList *)NULL;
       TmpListReglNum  = TmpListReglNum->NEXT
     )
  {
    if ( TmpListReglNum->REGLE_NUM == Value )
    {
      DRUC_EXIT( DRUC_ERROR_RULE_NUMBER );
    }
  }
  DrucStructRegle.REGLE_NUM [ DrucIndexMesure ] = Value;
  TmpListReglNum                                = DrucStructRegle.LIST_REGLE_NUM;
  DrucStructRegle.LIST_REGLE_NUM                = (DataList *)malloc( sizeof( DataList ));
  ( DrucStructRegle.LIST_REGLE_NUM )->NEXT      = TmpListReglNum;
  ( DrucStructRegle.LIST_REGLE_NUM )->REGLE_NUM = Value;
}
/*------------------------------------------------------------\
|                                                             |
|                  DrucInitRegleInstruction                   |
|                                                             |
\------------------------------------------------------------*/
void DrucInitRegleInstruction ( Instruction )
      int Instruction;
{
  DrucStructRegle.INSTRUCTION = Instruction;
}
/*------------------------------------------------------------\
|                                                             |
|                  DrucInitRegleRelation                      |
|                                                             |
\------------------------------------------------------------*/
void DrucInitRegleRelation ( Relation,
                             DrucIndexMesure
                           )
     int Relation;
     int DrucIndexMesure;
{
  DrucStructRegle.RELATION [ DrucIndexMesure ] = Relation;
}
/*------------------------------------------------------------\
|                                                             |
|                  DrucInitRegleLayerA                        |
|                                                             |
| Verifie que le Name est dans la liste des layers RDS        |
| ou                                                          |
| Verifie que le Name est dans la liste des layers            |
| user deja declares pour DRUC                                |
| ou sort                                                     |
|Range le numero de layer RDS dans DrucStructRegle.LAYER_1    |
\------------------------------------------------------------*/
void DrucInitRegleLayerA ( Name )
     char *Name;
{
  int IndexLayer = 0;

  /*\
   *  Le nom existe dans la liste des layers RDS
  \*/
  while( IndexLayer < RDS_MAX_LAYER )
  {
    if ( strncmp ( RDS_LAYER_NAME[ IndexLayer ],
                   Name ,
                   strlen (Name)
                 )
         == 0
       )
    if ( DrucStructRdsLayer[ IndexLayer ].RDS_INDEX == IndexLayer 
       )
    {
      DrucStructRegle.LAYER_1 = DrucStructRdsLayer[ IndexLayer ].RDS_INDEX;
      return;
    }
    IndexLayer ++ ;
  }
  /*\
   *  Le nom existe dans la liste des layers USER
  \*/
  if ( DrucStructDefine.USER_LAYER_NAME_0 != (char *)NULL )
  {
    if ( strstr( DrucStructDefine.USER_LAYER_NAME_0, Name ) != (char *)NULL )
    {
      DrucStructRegle.LAYER_1 = DRUC_USER_LAYER_0;
      return;
    }
  }
  if ( DrucStructDefine.USER_LAYER_NAME_1 != (char *)NULL )
  {
    if ( strstr( DrucStructDefine.USER_LAYER_NAME_1, Name ) != (char *)NULL )
    {
      DrucStructRegle.LAYER_1 = DRUC_USER_LAYER_1;
      return;
    }
  }
  if ( DrucStructDefine.USER_LAYER_NAME_2 != (char *)NULL )
  {
    if ( strstr( DrucStructDefine.USER_LAYER_NAME_2, Name ) !=
     (char *)NULL )
    {
      DrucStructRegle.LAYER_1 = DRUC_USER_LAYER_2;
      return;
    }
  }
  DRUC_EXIT( DRUC_ERROR_UNDEFINED_LAYER );
}
/*------------------------------------------------------------\
|                                                             |
|                  DrucInitRegleLayerB                        |
|                                                             |
| Verifie que le Name est dans la liste des layers RDS        |
| ou                                                          |
| Verifie que le Name est dans la liste des layers            |
| user deja declares pour DRUC                                |
| ou sort                                                     |
|Range le numero de layer RDS dans DrucStructRegle.LAYER_2    |
\------------------------------------------------------------*/
void DrucInitRegleLayerB ( Name )
     char *Name;
{
  int IndexLayer = 0;

  /*\
   *  Le nom existe dans la liste des layers RDS
  \*/
  while( IndexLayer < RDS_MAX_LAYER )
  {
    if ( strncmp ( RDS_LAYER_NAME[ IndexLayer ], 
                   Name , 
                   strlen (Name) 
                 ) 
         == 0
       )
    if ( DrucStructRdsLayer[ IndexLayer ].RDS_INDEX == IndexLayer 
       ) 
    {
      DrucStructRegle.LAYER_2 = DrucStructRdsLayer[ IndexLayer ].RDS_INDEX;
      return;
    }
    IndexLayer ++ ;
  }
  /*\
   *  Le nom existe dans la liste des layers USER
  \*/
  if ( DrucStructDefine.USER_LAYER_NAME_0 != (char *)NULL )
  {
    if ( strstr( DrucStructDefine.USER_LAYER_NAME_0, Name ) != (char *)NULL )
    {
      DrucStructRegle.LAYER_2 = DRUC_USER_LAYER_0;
      return;
    }
  }
  if ( DrucStructDefine.USER_LAYER_NAME_1 != (char *)NULL )
  {
    if ( strstr( DrucStructDefine.USER_LAYER_NAME_1, Name ) != (char *)NULL )
    {
      DrucStructRegle.LAYER_2 = DRUC_USER_LAYER_1;
      return;
    }
  }
  if ( DrucStructDefine.USER_LAYER_NAME_2 != (char *)NULL )
  {
    if ( strstr( DrucStructDefine.USER_LAYER_NAME_2, Name ) != (char *)NULL )
    {
      DrucStructRegle.LAYER_2 = DRUC_USER_LAYER_2;
      return;
    }
  }
  DRUC_EXIT( DRUC_ERROR_UNDEFINED_LAYER );
}
/*------------------------------------------------------------\
|                                                             |
|                  DrucInitRegleMesure                        |
|                                                             |
\------------------------------------------------------------*/
void DrucInitRegleMesure ( Mesure,
                           DrucIndexMesure
                         )
     int Mesure;
     int DrucIndexMesure;
{
  DrucStructRegle.MESURE [ DrucIndexMesure ] = Mesure;
}
/*------------------------------------------------------------\
|                                                             |
|                  DrucInitRegleValeur                        |
|                                                             |
\------------------------------------------------------------*/
void DrucInitRegleValeur ( Value,
                           DrucIndexMesure
                         )
     long Value;
     int  DrucIndexMesure;
{
DrucViewString ("DrucInitRegleValeur");
DrucViewNumber (Value);

  if ( ( DrucStructRegle.MESURE [ DrucIndexMesure ] == DRUC_MESURE_SURFACE )      ||  
       ( DrucStructRegle.MESURE [ DrucIndexMesure ] == DRUC_MESURE_SURFACE_INTER )
     )
  {
    Value  = ( RprTranslateParam ( 1.0 ) * Value );
  }
  DrucStructRegle.VALEUR [ DrucIndexMesure ] = Value;
  if ( ( DrucStructRegle.MESURE [ DrucIndexMesure ] == DRUC_MESURE_AXIALE )      ||
       ( DrucStructRegle.MESURE [ DrucIndexMesure ] == DRUC_MESURE_GEODESIQUE )
     )
  {  
/*\
    DrucCtmMax = ( DrucCtmMax > Value ?
                   DrucCtmMax :
                   Value
                 );
 * la ctm max est calculee par le parser 
 * comme ca on peut charger en tete les layers valides 
 * suivis des regles et de leure duplications
\*/
    DrucStructRdsLayer[ DrucStructRegle.LAYER_1 ].CTM = Value;
  }
}
/*------------------------------------------------------------\
|                                                             |
|                  DrucInitRegleOpCompare                     |
|                                                             |
\------------------------------------------------------------*/
void DrucInitRegleOpCompare ( Operateur,
                              DrucIndexMesure
                            )
     int Operateur;
     int DrucIndexMesure;
{
  DrucStructRegle.OP_COMPARE [ DrucIndexMesure ] = Operateur;
}
/*------------------------------------------------------------\
|                                                             |
|                  DrucStoreInstructionRegle                  |
|                                                             |
| Ecrit dans le fichier *TmpFileAssembler, l'instruction      |
| contenue dans DrucStructRegle avec ses valeurs              |
| Stocke le checksumm des ecritures dans DrucCheckSumm        |
| Une instruction de relation est caracterisee par un code    |
| RELATION dans ce cas deux layers sont enregistres au lieu   |
| d'un seul. Les autre valeurs sont toutes enregistrees       |
\------------------------------------------------------------*/
void DrucStoreInstructionRegle ()
{
int TmpIndexMesure;

  fprintf( TmpFileAssembler,
           "%d ",
           DRUC_ASM_BEGIN_REGLE
         );
  DrucComputeCheckSumm( DRUC_ASM_BEGIN_REGLE );

  fprintf( TmpFileAssembler,
           "%d ",
           DrucStructRegle.INSTRUCTION
         );
  DrucComputeCheckSumm( DrucStructRegle.INSTRUCTION );

  fprintf( TmpFileAssembler,
           "%d ",
           DrucStructRegle.LAYER_1
         );
  DrucComputeCheckSumm( DrucStructRegle.LAYER_1 );

  fprintf( TmpFileAssembler,
           "%d ",
           DrucStructRegle.LAYER_2
         );
  DrucComputeCheckSumm( DrucStructRegle.LAYER_2 );

  for ( TmpIndexMesure = 0;
        TmpIndexMesure < DRUC_MAX_MESURES;
        TmpIndexMesure ++
      )
  {
    fprintf( TmpFileAssembler,
             "%d ",
             DrucStructRegle.REGLE_NUM [ TmpIndexMesure ]
           );
    DrucComputeCheckSumm( DrucStructRegle.REGLE_NUM [ TmpIndexMesure ] );

    fprintf( TmpFileAssembler,
             "%d ",
             DrucStructRegle.RELATION [ TmpIndexMesure ]
           );
    DrucComputeCheckSumm( DrucStructRegle.RELATION [ TmpIndexMesure ] );

    fprintf( TmpFileAssembler,
             "%d ",
             DrucStructRegle.MESURE [ TmpIndexMesure ]
           );
    DrucComputeCheckSumm( DrucStructRegle.MESURE [ TmpIndexMesure ] );

    fprintf( TmpFileAssembler,
             "%d ",
             DrucStructRegle.OP_COMPARE [ TmpIndexMesure ]
           );
    DrucComputeCheckSumm( DrucStructRegle.OP_COMPARE [ TmpIndexMesure ] );

    fprintf( TmpFileAssembler,
             "%d ",
             DrucStructRegle.VALEUR [ TmpIndexMesure ]
           );
    DrucComputeCheckSumm( (int)DrucStructRegle.VALEUR [ TmpIndexMesure ] );

    DrucStructRegle.REGLE_NUM  [ TmpIndexMesure ] = DRUC_UNDEFINED_REGLE;
    DrucStructRegle.RELATION   [ TmpIndexMesure ] = DRUC_UNDEFINED_RELATION;
    DrucStructRegle.MESURE     [ TmpIndexMesure ] = DRUC_UNDEFINED_MESURE;
    DrucStructRegle.OP_COMPARE [ TmpIndexMesure ] = DRUC_UNDEFINED_OPERATEUR;
    DrucStructRegle.VALEUR     [ TmpIndexMesure ] = DRUC_UNDEFINED_VALEUR;

  }
  fprintf( TmpFileAssembler,
           "%d\n",
           DRUC_ASM_END_REGLE
         );
  DrucComputeCheckSumm( DRUC_ASM_END_REGLE );

  DrucStructRegle.LAYER_1 = DRUC_UNDEFINED_LAYER;
  DrucStructRegle.LAYER_2 = DRUC_UNDEFINED_LAYER;
}
/*------------------------------------------------------------\
|                                                             |
|                Druc Store Comment                           |
|                                                             |
\------------------------------------------------------------*/
void DrucStoreComment ()
{
  fputs( DRUC_DRC_COMMENT, 
         TmpFileAssembler );
  fputs( "\n", 
         TmpFileAssembler );
  fputs( DRUC_DRC_END_COMMENT, 
         TmpFileAssembler );
  fputs( "\n", 
         TmpFileAssembler );
}
/*------------------------------------------------------------\
|                                                             |
|                Druc Compiler Main                           |
|                                                             |
\------------------------------------------------------------*/
void main( argc , argv )
     int argc;
     char *argv[];
{
  int TmpResultat;

  if ( argc != 4 )
  {
    printf ( "Usage : %s rules_file rds_techno_file output_file\n",argv [0]);
    exit (1);
  }
  strcpy ( DRUC_OUTPUT_NAME,argv [2]);
  strcpy ( DRUC_TMP_OUTPUT_NAME,argv [3]);
 
  yyin = fopen ( argv [ 1 ] , "r" );
  if ( yyin == NULL )
  {
    DRUC_EXIT( DRUC_ERROR_IN_FILE );
  }
  mbkenv ();
  rdsenv ();
  loadrdsparam ();
  TmpResultat = yyparse();
  fclose( yyin );
  DRUC_EXIT ( TmpResultat );
};

